原型与继承

1.js是通过原型链来实现继承

基本思想是利用原型的一个引用类型继承另一个引用类型的属性和方法。原型对象将包含一个指向另一个原型的指针,而另一个原型的指针又指向它的构造函数。子类的prototype指向父类的实例。

所有对象的根类都是空的Object

var A = function(){};
A.prototype = { name: 'sven'};

var B = function(){};
B.prototype = new A();

var b = new B();
console.log(b.name);

2.确定原型和实例的关系

1).instanceof
2).isPrototypeOf()

3.继承方法

如果直接使用原型链继承,那么instance的构造函数是指向SuperType
缺点:
1).引用类型值的原型属性会被所有实例共享,所以其中一个实例修改了,其他所有实例也会跟着变化
2).实例初始化无法传递参数,因为原型指向的是父类的构造函数,所以传参也没用

1).经典继承

通过apply,call继承父类原型,在子类原型中添加自己的属性

function SuperType(name){
    this.name = name;
}

function SubType(){
    //继承SuperType
    SuperType.call(this,"Tom");
    //自定义子类属性
    this.age = '29;
}

var instance = new SuvType();
alert(instance.age); //29
2).组合式继承

子类通过借用构造函数(applay,call)继承父类的实例属性的继承,通过原型链对原型属性和方法的继承
缺点:调用2次父类的构造函数

function SuperType(name){
    this.name = name;
}
SuperType.proptotype.sayName = function(){ alert(this.name) }

function SubType(){
    //继承SuperType的构造函数属性和方法
    //第二次调用SuperType
    SuperType.call(this,"Tom");
    this.age = '29;
}

//继承SuperType的原型链的属性和方法
//第一次调用SuperType()
subType.prototype = new SubperType();
subType.constructor = subType;
3).原型式继承

基于上一个实例封装,目得就是为了实例共享

var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] };
var anotherPerson = Object( person); 

anotherPerson.name = "Greg"; 
anotherPerson.friends.push(" Rob");

//ES6新方法
var yetAnotherPerson = Object.create(person,
    {
        name: {value: "Linda"},
    }
);
console.log( anotherPerson.friends);//"Shelby, Court, Van, Rob, Barbie"
4).寄生式继承

原型式继承的改进。简单地给对象添加函数

var person = { name: "Nicholas", friends: ["Shelby", "Court", "Van"] };

function createAnother(original){ 
    var clone = Object(original); 
    //添加新方法,增强
    clone. sayHi = function(){alert(" hi"); }; 
    return clone;
}

var anotherPerson = createAnother(person); 
anotherPerson.sayHi(); //"hi"
5).寄生组合式继承

最终BOSS,解决伪继承的缺点,极组合式继承和寄生式继承优点

function inheritPrototype(subType, superType){ 
    //创建对象
    var prototype = Object(superType.prototype);  
    //增强对象 
    .....
    prototype.constructor = subType;
    //指定对象
    subType.prototype = prototype; 
}

function SuperType(name){
    this.name = name;
}
SuperType.proptotype.sayName = function(){ alert(this.name) }

function SubType(){
    SuperType.call(this,"Tom");
    this.age = '29;
}

//不直接new superType,而是浅复制它的原型
inheritPrototype(subType,superType)
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容