前言
理清、搞懂JavaScript原型链与继承
牢记以下内容
- prototype 是函数的固有属性
- _proto_ 是对象的固有属性
- 由于js里,函数也是对象,所以函数同样具有_proto_
- 普通函数的prototype无用,只有作为构造函数的function,才作分析,以下“函数”皆为“对象的构造函数”
- 对象的__proto__指向函数的prototype
- 函数的prototype指向函数的原型
- 函数的prototype具有constructor属性,指向函数本身
- __proto__与prototype的关系,形成了原型链
继承
实现完全继承,要满足以下几点,以函数B继承函数A举例
- 函数B的prototype具备__proto__属性,且此属性指向函数A的prototype
- 函数B的prototype具备constructor属性,且此属性指向函数B
- 函数B内执行函数A,且传递相应的参数
由此可推出继承的写法:
function A(name) {
}
function B(name) {
A.call(this, name); // 函数B内执行函数A,且传递相应的参数
}
B.prototype = Object.create(A.prototype); // 使B.prototype的__proto__指向A.prototype
B.prototype.constructor = B; // 使B.prototype的constructor指向B
为何这样写?
举例有Child,Parent,Grandparent 三个构造函数,形成继承关系,创建对象test,
const test = new Child(),则满足以下规则:
test._proto_ ——》Child.prototype
Child.prototype._proto_ ——》Parent.prototype
Parent.prototype._proto_ ——》Grandparent.prototype
满足此规则,则在查询对象test里的方法和属性时,会根据原型链,依次向上查找
B.prototype = Object.create(A.prototype);
此方法使得原型链的构成成立
B.prototype.constructor = B;
此方法让由B创建的对象,其constructor指向B。若无此方法,则指向A
其他
关于混合继承,推荐阅读Object.create()相关文档
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/create