20200221
Plan
- 你不知道的 js
Notes
原型链上的属性设置和屏蔽
a = { a: "a" };
Object.defineProperties(a, {
a1: {
value: "a1",
writable: false
},
a2: {
get() {
return this.a;
},
set(val) {
this.a = val;
}
}
});
b = Object.create(a);
b.b = "b";
b.a1 = "b1"; // 静默失败
b.a2 = "b2";
/**
* b {
* a: "b2",
* a2() // setter, 被拷贝到了当前obj, setter 无法用delete删除
* b: "b"
* }
* **/
第二种情况,当前没有 setter,原型链式有:
a = { a: "a" };
b = Object.create(a);
Object.defineProperties(a, {
a1: {
value: "a1",
writable: false
},
a2: {
get() {
return this.a;
},
set(val) {
this.a = val;
}
}
});
b.a2 = "b2"; // 无论是先继承还是先设置setter, b下面都会出现a2的setter
关联 prototype
function Base() {}
function Sub() {
Base.call(this);
}
// 第一种方案
Sub.prototype = new Base(); // 有副作用,会调用两次,如果有写文件操作就会触发两次写文件
// 第二种
Sub.prototype = Object.create(Base); // 解决第一种方案的问题,但是直接替换了Sub.prototype
// 第三种
Object.setPrototypeOf(Sub.prototype, Base.prototype); // 不会丢失Sub.prototype
bind 返回的函数,没有 prototype。如果用 instanceof 来判断的话,目标函数的 prototype 会代替绑定函数的 prototype。B.prototype 会代替 C.prototype
function B() {}
let C = B.bind(null);
C.prototype === null; // true
// 如果用 instanceof 来判断的话,目标函数的 prototype 会代替绑定函数的 prototype。B.prototype 会代替 C.prototype
C instanceof B; // false; 等价于 B instanceof B
isPrototypeOf 来判断原型链式是否存在 B