1.[[prototype]]
var anotherObject = {
a:2
};
var myObject = Object.create(anotherObject);
myObject.a; //2
Object.create(...)会创建一个关联到anotherObject的对象,尽管myObject中并没有a属性,但是顺着原型链找到了anotherObject的a属性,也就是说anotherObject在原型链的的上面,而myObject在原型链的下面
属性的遍历
var anotherObject = {
a:2
};
var myObject = Object.create(anotherObject);
for(var k in myObject) {
console.log("found: " + k);
}
// found: a
("a" in myObject); //true
for .. in 遍历对象时的原理和查找[[prototype]]链类似,任何可以通过原型链访问到的属性都会被枚举
[[prototype]]的尽头
所有普通的 [[prototype]]链都会指向内置的Object.prototype
属性设置和屏蔽
屏蔽:在原型链底端的属性会屏蔽上面所有名字相同的属性
设置:Object.defineProperty(...)
2.原型继承
es6之前,将Bar.prototype关联到Foo.prototype的方法
Bar.prototype = Object.create(Foo.prototype);
es6之后直接修改现有的Bar.prototype
Object.setPrototypeOf(Bar.prototype,Foo.prototype);
instanceof操作符的左操作数是一个普通的对象,右操作数是一个函数。instanceof回答的问题是:
在a的整条[[prototype]]链中是否有Foo.prototype指向的对象,这个方法只适用与对象与函数之间
a instanceof Foo;
isPrototypeOf判断[[prototype]]反射的方法
Foo.prototype.isPrototypeOf(a);
这个方法回答的问题是:在a的整个[[prototype]]链中是否出现过Foo.prototype
Object.getPrototypeOf( a );
这个方法可以直接获取一个对象的[[prototype]]链
.__proto__属性引用了内部的[[prototype]]对象
.__proto__的实现
Object.defineProperty(Object.prototype, "__prototype__",{
get: function() {
return Object.getPrototypeOf(this);
},
set: function() {
Object.setPrototypeOf(this , o);
return o;
}
}
3.对象关联
Object.create在旧版本中的polyfill代码
if(!Object.create) {
Object.create = function(o) {
function F(){}
F.prototype = o;
return new F();
};
}
这段polyfill代码使用了一个一次性函数F,我们通过改写它的 .prototype属性使其指向想要关联的对象,然后再返回new F()给Object.create构造一个新对象进行关联
4.小结
所有普通对象都有内置的Object.prototype,指向原型链的顶端,如果在原型链中找不到指定的属性就会停止。toString(),valueOf()和其他的一些通用功能都存在于Object.prototype对象上,因此语言中的所有对象都可以使用它们。