function Car () { this.color = "red"; } Car.prototype.sayHi=function(){ console.log('你好') }
var car =new Car(); var car2 = Object.create(Car);
var obj={}; obj.__proto=Car.prototype Car.call(obj)
第一步,建立了一个空对象obj
第二步,将空对象的__proto__成员指向了Car函数的原型属性,该原型属性是一个原型对象,也就意味着obj的原型属性上拥有了Car.prototype中的属性或方法javascript
第三步,将Car函数中的this指针指向obj,obj有了Car构造函数中的属性或方法 ,而后Car函数无返回值或返回的不是对象,直接返回obj,不然返回Car函数中的对象java
tip:__proto__是什么浏览器
每一个对象都有一个[[prototype]}属性,这个属性是隐藏属性,谁建立了它,该属性就指向谁的prototype属性,由于是隐藏属性,不能直接访问,因此有的浏览器提供了一个__proto__属性来访问,然而这不是一个标准的访问方法,因此ES5中用Object.getPrototypeOf函数得到一个对象的[[prototype]]。ES6中,使用Object.setPrototypeOf能够直接修改一个对象的[[prototype]]函数
Object.create()
方法建立一个新对象,并使用现有的对象来提供新建立的对象的__proto__,关键代码以下this
关键代码以下:prototype
Object.create = function (o) { var F = function () {}; F.prototype = o; var newObj=new F(); return newObj; };
能够看到Object.create内部建立了一个新对象newObj,默认状况下newObj.__proto__== F.prototype,在本例中则重写了构造函数F的原型属性,最终的原型关系链为newObj.__proto__== F.prototype == o指针
若是现有的对象是一个构造函数,即var car2=Object.create(Car)会发生什么呢?code
console.log(car2.color) //undefined console.log(car2.sayHi()) //undefined
执行代码发现都是undefined, 为何会这样呢?对象
问题1:由于Object.create内部的新对象是new F()建立的,跟Car构造函数没有半毛钱的关系,因此天然不能访问到Car中的属性了blog
问题2:调用car2.sayHi()时首先判断car2对象有没有相应的方法,若是没有,则查找car2的原型链上有没有该方法,car2的原型属性是Car构造函数(能够经过car2.__proto__来证实),构造函数没有sayHi方法,天然也就是undefined了。
那若是将var car2=Object.create(car)又发生了什么呢?
function Car () { this.color = "red"; this.person={name:'张三'} } Car.prototype.sayHi=function(){ console.log('你好') } var car =new Car(); var car2 = Object.create(car); car2.person.name ='李四' console.log(`car是${car.person.name},car2是${car2.person.name}`)
至关于实现了原型继承方式(注意不是原型链继承),本质上来讲是对一个对象进行了浅拷贝
最终结论:
1. Object.create(o),若是o是一个构造函数,则采用这种方法来建立对像没有意义
2.Object.create(o),若是o是一个字面量对象或实例对象,那么至关因而实现了对象的浅拷贝