关于一些原型链继承的学习经验和总结

原型对象中方法中的this 就是实例对象

构造函数中的this就是实例对象

使用字面量改写原型会使原型指向失效,需要重写原型指向,添加上

 constructor:原构造器名称

 

举个例子:要使A继承B的属性和方法 格式如下 A.prototype = new B();

现在可能会有疑问,为什么不是A.prototype = B(A.prototype = B.prototype;)?

这里需要捋顺一下引用赋值跟传值赋值的区别,引用类型赋值时,原来的变量的值改变会间接影响被赋值对象的值。而存放在基本栈区的基本类型则不会(传值赋值)。

可能传值赋值说的有点绕,不懂得可以看下面,举个例子

1 var a=100;
2 var b=a;
3 
4 //这里a和b是没有任何关系的,a赋值给b是指a的值100,这个100赋值给了b,即完成这个操作.

那接着说,为什么不是A.prototype = B(A.prototype = B.prototype;)?

因为这样相当于引用了,继承的原则就是子类的改变不影响父类,若是引用的话效果就会适得其反了。

 1 function B(){
 2    this.b=function(){alert("我是B")};
 3 }
 4 
 5 function A(){
 6     this.a=function(){alert("我是A")};
 7 }
 8 
 9 //这里开始A继承B
10  
11 A.prototype=new B();             //这里A.prototype已经指向B实例
12 //等号右边相当于: var b =new B();
13 //最后 A.prototype=b;
14 A.prototype.constructor=A;
15 //因为这里构造器指向被改变,所以需要重写
16 
17 //做个测试
18 console.log(A.prototype.b)       //输出"我是B",原型链已经接上了。
19  
20 //再做一个测试 
21 var b=new B();
22 A.prototype.b=function(){alert("我改变了B")}; 
23 console.log(A.prototype.b)       //输出"我改变了B"
24 console.log(b.b)       //输出"我是B"
25 
26 //很明显并没有改变B.prototype中的属性和值    

 

刚在写上面代码的时候,我遇到一个问题

function B() {
this.b = function() {
console.log("我是B")
}
}
console.log(B.prototype.b);    //Undefined

//我会这么直接输出是因为之前说过B.proptotype的创建过程其实就是B实例化后给prototype重新设置了值
//基于上面这点,B.protopyte是一个拥有B的一切属性和方法的,是一个对象,对象调用里面的方法应该是可行的。
//上面A.prototype.b可行的原因是,11行中A继承了B,这点在笔者写完这篇文章还是没有想通,如果有懂的大佬可以评论指点,我会整理更新出这个知识点出来

 

跳过上面那个问题,继续下面接着说,所以要使用new B();实例化一个对象xx,这个xx继承了B的属性和方法,根据原型链,A可以通过xx访问到B的属性和方法。

而且通过A.prototype在原型对象上改变或者添加属性时,并不会影响B.prototype的原态。

最后,总结一下,要搞懂原型继承就要搞懂原型链的原理,那之后的延伸知识点自然就不攻自破了!

 

 

更新:针对上面那个问题,我查阅了一翻资料,得出的结论

  •  通过原型链继承时,不会检索构造函数内的标识符,即原型对象被创建时,里面是不包含构造函数里以声明过的属性和方法。
posted on 2020-09-01 04:38  Rocn  阅读(131)  评论(0)    收藏  举报