1 继承
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=Object.create(Foo.prototype);
Bar.prototype.myLabel=function () {
return this.label;
}
var a=new Bar("a","obj a");
console.log(a.myName());// a
console.log(a.myLabel());// obj a
核心代码:Bar.prototype=Object.create(Foo.prototype)
比较:
Bar.prototype=Foo.prototype 不会创建一个关联到Bar.prototype的新对象,只是让Bar.prototype直接引用Foo.prototype,因此修改Bar.prototype.xxx时,Foo.prototype也会同时修改。
Bar.prototype=new Foo() 会创建一个关联到Bar.prototype的新对象,但这是Foo(...)的构造函数调用,如果函数Foo有一些副作用(比如写日志,修改状态,给this添加数据属性),会影响Bar()。
而且会额外在__porto__中继承Foo本身的属性
Bar.prototype=Object.create(Foo.prototype) Bar.prototype=new Foo()
2 Object.setPrototypeOf()修改对象的[[prototype]]关联
Bar.prototype=Object.create(Foo.prototype); //es6前的写法 推荐:因为更短,可读性高
Object.setPrototypeOf(Bar.prototype,Foo.prototype);
3 判断[[prototype]]关联
instanceof: 只能处理函数和对象之间的关系
isPrototypeOf:一个对象是否存在于另一个对象的原型链上
function Foo(name){
this.name=name;
}
Foo.prototype.myName=function() {
return this.name;
}
var a=new Foo("123");
var b=new Foo("456");
console.log(a instanceof Foo);// true a的整条[[prototype]]链中是否指向Foo.prototype的对象
console.log(Foo.prototype.isPrototypeOf(b));// true b的整条[[prototype]]链中是否出现 Foo.prototype
console.log(Foo.isPrototypeOf(b));// false
console.log(a.isPrototypeOf(b));// false
4 获取[[prototype]]链
Object.getPrototype() || __proto__
function Foo(name){
this.name=name;
}
Foo.prototype.myName=function() {
return this.name;
}
var a=new Foo("123");
console.log(Object.getPrototypeOf(a) === Foo.prototype) //true
console.log(a.__proto__ === Foo.prototype) // true
.__proto__实际上不存在于你正在使用的对象中(本例是a),而是和.toString()这些存在内置的Object.prototype
注意:最好把[[prototype]]对象关联看作只读特性,从而增加代码的可读性。
5 Object.create() 创建一个新对象并把它关联到指定的对象
Object.create(null) 创建一个拥有空[[prototype]]链的对象,这个对象无法进行委托,一般这种对象称为字典由于完全不受原型链干扰,很适合来存储数据。
polyfill代码
if(!Object.create()){
Object.create=function(o){
function F(){};
F.prototypr=o;
return new F();
}
}