JavaScript原型继承

原型继承要点:

一、每创建一个函数,就会同时创建一个它的prototype对象,这个对象(原型)也会自动获得constructor属性,并指向原函数。

二、所有引用类型默认都继承自Object,而这个继承也是通过原型链实现的。

三、所有函数的默认原型都是Object的实例,因此默认原型都会包含一个内部指针__proto__,指向 Object.prototype。而Object.prototype的constructor属性指向Object。注:使用对象字面量表示法新建(实例化)一个对象时,等同于new Object(),例如 var a = { };其实例 a 的prototype属性指向Object的原型Object.prototype,而原型的constructor属性指向Object。

四、当用构造函数实例化对象时,实例中的内部指针(__proto__)仅指向原型,而不指向构造函数。

五、属性继承只在读取属性值的时候发生,而当写入属性值的时候不会发生。

原型链的问题:

1、包含引用类型值的原型属性会被所有实例共享,但基本类型不会。

2、在创建子类型的实例时,不能向超类型的构造函数中传递参数。

DEMO

//包含引用类型的原型属性会被所有实例共享,但基本类型不会。
function SuperType(){
    this.supp = ['supP'];
    this.supq = 'supQ';
}

function SubType(){}

SubType.prototype = new SuperType();

var sub1 = new SubType();
sub1.supp.push('aaa');
sub1.supq = 'bbb';
var sub2 = new SubType();
console.log('sub2.supp: ' + sub2.supp);  //sub2.supp: supP,aaa
console.log('sub2.supq: ' + sub2.supq);  //sub2.supq: supQ
//下面这个更有意思
sub1.supp = [1, 2];
console.log('sub1.supp: ' + sub1.supp);  //sub1.supp: 1,2
console.log('sub2.supp: ' + sub2.supp);  //sub2.supp: supP,aaa
//为什么会这样呢?因为sub1.supp = [1, 2]操作,是在sub1当前环境的变量对象中添加了一个属性supp,
//并指向[1, 2]。而不是沿作用域链,修改原型对象中的supp属性。
//属性继承只在读取属性值的时候发生,而当写入属性的时候不会发生。
console.log('sub1.__proto__.supp: ' + sub1.__proto__.supp);  //sub1.__proto__.supp: supP,aaa

  

参考书籍:

JavaScript高级程序设计

JavaScript权威指南

原文地址:https://www.cnblogs.com/realwall/p/2344522.html