[[Prototype]]
属性设置与屏蔽
myObject.foo = "bar";
如果 foo 不直接存在于 myObject 中,而是存在于原型链上层时执行这条赋值命令。
- 如果在 [[Prototype]] 上层存在名为
foo的普通数据访问属性,则直接在 myObject 中添加新的foo属性,是屏蔽属性。 - 如果在 [[Prototype]] 上层存在名为
foo的只读 (writable:false) 属性, 则这条赋值语句会被忽略,在严格模式下报错。 - 如果在 [[Prototype]] 上层存在名为
foo的Setter,那么就一定会调用这个 Setter。不会在 myObject 中添加新的foo属性。
使用 Object.defineProperty(..) 在任何情况下都可以在 myObject 中添加 foo 属性。
小心隐式屏蔽
var anotherObject = { a: 2 };var myObject = Object.create(anotherObject);anotherObject.a; //2myObject.a; //2anotherObject.hasOwnProperty("a"); //truemyObject.hasOwnProperty("a"); //falsemyObject.a++; //隐式屏蔽 => myObject.a = myObject.a + 1;anotherObject.a; //2myObject.a; //3myObject.hasOwnProperty("a"); //true
“构造函数”
function Foo() {//...}var a = new Foo();
使用 new 来调用函数,会自动执行下面的操作:
- 创建一个全新的对象
- 将新的对象
[[Prototype]]关联到函数的.prototype - 将新的对象绑定到函数调用的 this
- 如果函数没有返回其他对象,那么
new表达式中的函数调用会自动返回这个新对象。
function Foo() {//...}Foo.prototype = {/* ... */};var a = new Foo();a.constructor === Foo; //falsea.constructor === Object; //true
a.constructor 委托给了 Foo.prototype,而 Foo.prototype 的 .constructor 属性只是在 Foo 函数声明时的默认属性。
在将 Foo.prototype 指向空对象后,空对象中也没有 .constructor 属性, a.constructor 则委托给了委托链顶端的 Object.prototype,指向了 Object。
(原型)继承
function Foo(name) {this.name = name;}Foo.prototype.myName = function () {return this.name;};function Bar(name, label) {Foo.call(this, name);this.label = label;}//创建了一个新的 Bar.prototype 对象并关联到 Foo.prototype// Bar.prototype 现在没有 .constructorBar.prototype = Object.create(Foo.prototype);Bar.prototype.myLabel = function () {return this.label;};var a = new Bar("a", "obj a");a.myName(); // "a"a.myLabel(); // "obj a"
以下方法使错误的
// 和你想要的机制不一样 直接让 Bar.prototype 直接引用 Foo.prototype ,对其修改会直接修改 Foo.prototypeBar.prototype = Foo.prototype;// 基本上满足你的需求 但是可能会有一些副作用Bar.prototype = new Foo();
ES6 新特性
//ES6之前需要抛弃默认的 Bar.prototypeBar.prototype = Object.create(Foo.prototype);//ES6开始直接修改现有的 Bar.prototypeObject.setPrototypeOf(Bar.prototype, Foo.prototype);
检查“类”关系
待补充!!
Object.create(..) polyfill
if (!Object.create) {Object.create = function (o) {function F() {}F.prototype = o;return new F();};}
