欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

js中常见继承方式

程序员文章站 2022-07-09 20:12:33
1.原型模式 function Father(){ this.property = true; } Father.prototype.getValue = function(){ return this.property; } function Son(){ this.Sonproperty = f ......

1.原型模式

function father(){
this.property = true;

}
father.prototype.getvalue = function(){

return this.property;
}
function son(){
this.sonproperty = false;
}
//继承father
son.prototype = new father();//原型重写,contructor被改写
son.prototype.construtor = son;//重新指向son
son.prototype.getsonvalue = function(){
return this.property;
}
var instance = new son();
console.log(instance.getvalue());
/*缺点:
1.引用原型值会被所有实例共享
2.子类无法向父类传参
*/
2.借用函数继承(经典继承)
 
//基本思想:在子类型构造函数中调用超类型的构造函数
function father(){
this.colors = ["red","blue","green"];
name = "haha";
}

function son(){
father.call(this);//继承father,并向父类型传参

}
son.prototype = new father;
var instance1 = new son();
instance1.colors.push("black");
console.log(instance1.colors);

instance2 = new son();
instance2.colors.push("pink");
console.log(instance2.colors);
/*
解决了原型链所存在的两个问题
但是依然存在构造函数方法无法复用的问题
*/

3.组合继承(伪经典继承)---经常使用
 
// //集合原型和构造两者之长
// //基本思想: 使用原型链实现对原型属性和方法的继承,通过借用构造函数来实现对实例属性的继承.
function father(name){
this.name = name;
this.colors = ["red","pink","green"];
}

father.prototype.sayname = function(){
console.log(this.name);
}

function son(name,age){
father.call(this,name);//使用构造函数进行实例属性的继承
this.age = age;
}

son.prototype = new father();//使用原型链继承超类型方法
son.prototype.constructor = son;//重新指向son
son.prototype.sayage = function(){
console.log(this.age);
}

var instance1 = new son("lisi",12);
instance1.colors.push("brown");
console.log(instance1.colors);
instance1.sayname();
instance1.sayage();

var instance2 = new son("hah",22);
instance2.colors.push("black");
console.log(instance2.colors);
instance2.sayname();
instance2.sayage();

4.原型式继承(浅拷贝)

//原型式继承
/*基本思想:在object()函数内部, 先创建一个临时性的构造函数,
然后将传入的对象作为这个构造函数的原型,最后返回了这个临时类型
的一个新实例.*/
var person = {
name : "van",
friends : ["hah","yisi"]
};
var anotherperson = object.create(person);
anotherperson.friends.push("yixiu");
console.log(person.friends);
/*
和原型模式相同的是所有新对象依然共享含有引用类型值的属性
*/
5.寄生式继承
 
/*寄生式继承的思路与(寄生)构造函数和工厂模式类似,
即创建一个仅用于封装继承过程的函数,该函数在内部以
某种方式来增强对象,最后再像真的是它做了所有工作一样返回对象.*/
function createanother(original){
var clone = object.create(original);//先进行浅复制后增强对象
clone.sayhi = function(){//进行增强
console.log(1);
}
return clone;
}
var person = {
friends : ["hah","yisi"]
};
//缺点:无法进行函数复用,只能使用父类中的方法
// person.prototype.say = function(){
// console.log(2);
// }
var anotherperson = createanother(person);
anotherperson.friends.push("yixiu");
console.log(person.friends);
anotherperson.sayhi();
// anotherperson.say();
6.寄生组合式继承(结合前面的所有优点)
 
//寄生组合式继承就是为了降低调用父类构造函数的开销而出现的
//基本思路是: 不必为了指定子类型的原型而调用超类型的构造函数
function extend(subclass,superclass){
var f = function(){};
f.prototype = superclass.prototype;
//subclass.prototype =superclass.prtotype相当于原型共享而非继承
subclass.prototype = new f();//继承superclass的原型
subclass.prototype.constructor = subclass;//原型重写,手动绑定

subclass.superclass = superclass.prototype;//将superclass.prototype缓存起来,方便后续访问
if(superclass.prototype.constructor == object.prototype.constructor){
superclass.prototype.constructor = superclass;
}
}
function father(name){
this.name = name;
this.colors = ["red","pink","green"];
}

father.prototype.sayname = function(){
console.log(this.name);
}

function son(name,age){
father.call(this,name);//使用构造函数进行实例属性的继承,调用第一次
this.age = age;
}

extend(son,father);//
son.prototype.constructor = son;//重新指向son
son.prototype.sayage = function(){
console.log(this.age);
}

var instance1 = new son("lisi",12);
instance1.colors.push("brown");
console.log(instance1.colors);
instance1.sayname();
instance1.sayage();

var instance2 = new son("hah",22);
instance2.colors.push("black");
console.log(instance2.colors);
instance2.sayname();
instance2.sayage();