js原型与继承

1)关于原型

创建的新函数有一个prototype指针,指向一个原型对象。原型对象有一个construct属性,指回去函数,形成一个环。函数创建一个新实例后,实例会有一个内部属性__proto__ ,指向原型对象。

2)关于重写原型对象

一般我们给原型对象添加属性和方法的时候,都会这样添加:

Person.prototype.name="zakas";
Person.prototype.sayName=function(){
     console.log(this.name);  
}

如果用对象字面量的话:

Person.prototype={
     name:"zakas",
     sayName:function(){
           console.log(this.name);
     }
}

就会重写了整个原型对象,即constructor属性不再指向Person了。如果这个constructor的值真的重要的话,可以手动加入代码:

Person.prototype={
     constructor:Person,
     name:"zakas",
     sayName:function(){
           console.log(this.name);
     }
}

3)关于继承——原型链继承

SubType.prototype=new SuperType();

子函数要继承父函数的时候,将子函数的prototype指针指向一个父函数的实例,,父函数实例就会有一个__proto__属性,指向父函数的原型对象。

用子函数创建一个实例后,子函数实例的内部__proto__指向子函数的原型对象,子函数的原型对象(即父函数的实例)的内部__proto__指向父函数的原型对象。

原型链的缺点就是:

1、父函数里面的属性,在实例后,就变成了子函数的prototype对象的属性,如果这个属性是个引用类型的话(如数组),那么所有的子函数的实例将共享这 个属性(因为如果是基本类型的话,属性的赋值就会是在实例中添加新的属性,原型对象中的属性是不变的,但是如果是引用类型的话,如数组,往数组里面push数据是真的往原型对象的属性push数据);

2、子函数无法向父函数的构造函数传递参数

4)关于继承——借用构造函数

var SubType=function(){
       SuperType.call(this);
}

借用构造函数的缺点就是:

1、只是借用了父函数的构造函数,并没用借用到父函数的原型对象,就没有了所谓的函数复用

5)关于继承——寄生组合式

 1 var object=function(o){
 2     var F=function(){};
 3     F.prototype=o;
 4     return new F();
 5 };
 6 var inheritPrototype=function(subType,superType){
 7     var prototype=object(superType.prototype);
 8     prototype.constructor=subType;
 9     subType.prototype=prototype;
10 };
11 
12 var SuperType=function(name){
13     this.name=name;
14 };
15 SuperType.prototype.sayName=function(){
16     alert(this.name);
17 };
18 var SubType=function(name,age){
19     SuperType.call(this,name);
20     this.age=age;
21 };
22 inheritPrototype(SubType,SuperType);

 

寄生组合式的原理是:

1、第19行代码,用call解决了原型链的两个缺点。call只是借用了构造函数,然后其他就是下面一点了

2、object函数的作用,说得通俗一点,就是将SuperType的构造函数抽空,然后返回一个实例(为什么抽空构造函数呢,因为SuperType的构造函数已经用call解决了),然后inheritPrototype函数将SubType的原型对象设置为该实例


所以,寄生组合式真正实现了继承吧。。。。

5)关于instanceof

我们通常会用instanceof来判断一个变量是不是某个对象的实例

如obj instanceof class

那么内在是如何运作的,其实instanceof判断的而是obj原型链上的原型是否与class的原型是同一个对象,是返回true,不是返回false

所以说,用instanceof来判断一个变量是否是某个对象的实例是不精准的,任何一个函数,只要改写他的prototype,它都可能“成为某个实例的对象”

原文地址:https://www.cnblogs.com/zhrj000/p/2716843.html