原型对象中方法中的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的原态。
最后,总结一下,要搞懂原型继承就要搞懂原型链的原理,那之后的延伸知识点自然就不攻自破了!
更新:针对上面那个问题,我查阅了一翻资料,得出的结论
- 通过原型链继承时,不会检索构造函数内的标识符,即原型对象被创建时,里面是不包含构造函数里以声明过的属性和方法。
浙公网安备 33010602011771号