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()