Object.create内部原理

es5中可以采用Object.create来创建一个对象,看下面的例子

function Car () {
    this.color = "red";
}
Car.prototype.sayHi=function(){
  console.log('你好')
}
var car2 =  Object.create(Car);
console.log(car2.color); //undefined 
car2.sayHi(); //undefined

1.通过Object.create(Car)创建的对象无法访问构造函数中的属性

2.通过Object.create(Car)创建的对象无法访问构造函数原型对象中的属性或方法(sayHi)

为什么会这样呢,我们看看Object.create内部实现的关键代码

Object.create =  function (o) {
    var F = function () {};
    F.prototype = o;
    return new F();
};

Object.create内部的new F()创建了一个新对象,这个新对象不是o(对应例子中的Car)的实例,所以肯定访问不到Car构造函数中的属性了。


Tip:new F()时执行过程如下

1.创建一个新对象(此时这个对象为空)

2.将新对象的__proto__(即[[prototype]])指向构造函数的原型属性,假设构造函数是F,那么此新对象的__proto__指向的是F.prototype(F.prototype返回一个原型对象)

3.将F中的this指定为当前新对象


我们知道们new一个新对象时,默认情况下__proto__指向的是其构造函数的原型属性,在本例中则重写了构造函数F的原型属性,最终的原型关系链为newObj.__proto__== F.prototype == o

调用car2.sayHi()时首先判断car2对象有没有相应的方法,如果没有,则查找car2的原型链上有没有该方法,car2的原型属性是Car构造函数,构造函数没有sayHi方法,自然也就是undefined了,可以将代码修改一下,验证此条规则

Car.sayHi=function(){
  console.log('他好我也好')
}

也可以这样修改

var car2 =  Object.create(Car.prototype);
car2.sayHi()

  

猜你喜欢

转载自www.cnblogs.com/94pm/p/9113434.html