原型链
JavaScript的每个对象都有__proto__或称[[Prototype]]内部属性,储存引用另一个对象的,层层向上引用直到null。这条层层引用所行成的链,就是原型链。并且可以基于原型链进行基于对象的编程
e.g.
const o = {
a: 1,
b: 2,
// __proto__ 设置了 [[Prototype]]。它在这里被指定为另一个对象字面量。
__proto__: {
b: 3,
c: 4,
},
};
原型链为{ a: 1, b: 2 } ---> { b: 3, c: 4 } ---> Object.prototype ---> null
其中o.[[prototype]].b为2,访问的属性为原型链第一个有该属性的对象,即访问到了就不会继续向下访问。
__proto__ [[Prototype]]
Object.getPrototypeOf() 和 [Object.setPrototypeOf()]访问
⚠️区别function.prototype,function.prototype是function实例的[[Prototype]]
this
this会指向当前的对象
const parent = {
value: 2,
method() {
return this.value + 1;
},
};
console.log(parent.method()); // 3
// 当调用 parent.method 时,“this”指向了 parent
// child 是一个继承了 parent 的对象
const child = {
__proto__: parent,
};
console.log(child.method()); // 3
// 调用 child.method 时,“this”指向了 child。
// 又因为 child 继承的是 parent 的方法,
// 首先在 child 上寻找“value”属性。但由于 child 本身
// 没有名为“value”的自有属性,该属性会在
// [[Prototype]] 上被找到,即 parent.value。
child.value = 4; // 在 child,将“value”属性赋值为 4。
// 这会遮蔽 parent 上的“value”属性。
// child 对象现在看起来是这样的:
// { value: 4, __proto__: { value: 2, method: [Function] } }
console.log(child.method()); // 5
// 因为 child 现在拥有“value”属性,“this.value”现在表示
// child.value
构造函数 Constructor
构造函数就是给新建的对象设置__proto__。同时可以重写为类(语法糖)
e.g.
const boxPrototype = {
getValue() {
return this.value;
},
};
const boxes = [
{ value: 1, __proto__: boxPrototype },
{ value: 2, __proto__: boxPrototype },
{ value: 3, __proto__: boxPrototype },
];
使用构造函数简化:
//构造函数
function Box(value){
this.value=value
}
box.prototype.getValue=function(){
return this.value
}
const boxes=[new Box(1),new Box(2),new Box(3)]
prototype属性赋值
constructor属性 使用Object.setPrototypeOf赋值,直接赋值新对象会覆盖掉Constructor.prototype除原型外的constructor属性
function Base() {}
function Derived() {}
// 将 `Derived.prototype` 重新赋值为 `Base.prototype`,
// 以作为其 `[[Prototype]]` 的新对象
// 请不要这样做——使用 Object.setPrototypeOf 来修改它
Derived.prototype = Object.create(Base.prototype);
new 的方式继承和 Object.create() 实现的区别
new 的方式继承会执行constructor里的代码 Object.create 会直接创造新对象
检查
仅检查属性是否为 undefined 是不够的。该属性很可能存在,但其值恰好设置为 undefined
基于原型链的继承
当访问一个对象的属性时,在该对象搜索结束后,会沿着原型链继续搜索,直到搜索到该属性或搜索到null返回为undefined。