javascript Object.create()究竟发生了什么

 

  这是我在博客园的第一篇博客,早上看了一个大牛的博客,关于javascript继承的,对于大牛使用Object.create()实现继承的方式以为点问题,就本身研究了一下,因此就有了这篇帖子。javascript

本帖只讲Object.create()。由于我也才作一年前端,理解不对的,但愿大牛们帮忙指正。前端

  在博客开始前先谈下我多 prototype和__proto__的粗浅的认识。java

  一、prototype 只有类才有这个属性,通常经过函数声明 function xx(){} 和函数表达式 var xx=function(){} 定义的对象都有这个属性,而经过new生成的函数对象则没有这个属性。类的prototype属性指向类的原型对象函数

  二、__proto__  这个指向父类的prototype属性所指向的对象,即父类的原型对象; 函数声明和函数表达式定义的类的__proto__指向Object的原型对象function Empet(){}.好比 function A(){} ;  var a= new A(); a.__proto__和A.prototype指向的是同一个对象。this

  三、经过new 建立的对象是没有 prototype属性的spa

  先上一张图片,这样你们了解的比较清楚。图应该你们都看得懂,这里就不解释了。prototype

  基于以上粗浅的认识开始下面的探讨。翻译

  先建立类A调试

function A(){
    this.x="i am x"
}
var a =new A(); console.log("A.prototype : "+A.prototype+" ,A.__proto__ : "+A.__proto__);//A.prototype : [object Object] ,A.__proto__ : function Empet(){}验证第一点 console.log("a : "+a.prototype+" ,a.__proto__ : "+a.__proto__); //a : undefined ,a.__proto__ : [object Object] 验证第3点

  验证验证 第二点a.__Proto__ 就是 A.prototypecode

a.__proto__.getName=function(){
	console.log("create by a.__proto__");
}
var a2 =new A();
a2.getName();  //create by a.__proto__

  验证成功,经过new建立的对象的__proto__跟类的prototype指向同一个对象,即类的原型对象

 

  如今开始正题——Object.create 发生了什么

var obj =Object.create(A);

  《javascript权威指南》6.1节中说 Object.create()建立一个新对象,其中第一个参数是对象的原型。

  若是按照这种说法 obj.prototype 应该指向A;因此obj.prototype跟A拥有相同的方法和属性,如今为A定义一个show方法 看obj.prototype是否能调用这个show()方法

A.show=function(){
    return "i am A"
}
console.log("A.show(): "+A.show());  //A.show(): i am A

  A能调用show方法,验证obj.prototype 是否能调用show()方法

console.log("obj.prototype: "+obj.prototype.show());//报错 undefined is not a function

  oh,mygod,难道我心中的圣经《javascript权威指南》上写的是错的吗?我宁肯相信是我理解错了,或是翻译错了。

  通过断点调试发现,obj拥有__proto__属性而没有prototype属性。我前面也说过,在我粗浅的认识中, 只有经过new建立的对象才有这样的性质——有__proto__属性而没有prototype属性。因此我判定obj是经过new建立的对象。断点调试发现 obj的_proto__是指向A的。

  查阅了一下资料 微软的官方文档上是这样写的

  "Object.create()返回值为一个具备指定的内部原型且包含指定的属性(若是有)的新对象" 注意这里 "指定的内部原型" 指定的内部原型是__proto__ 而不是prototype。咦,难道真的是这样吗?

  若是是这样的话就是说  obj是new出来的对象, 在Object.create() 过程当中 产生了一个类 这个类是obj的父类。父类new出了obj这个实例对象。 父类的prototype是指向A的, 因此obj的__proto__就指向了A。

  为了验证这个想法,程序走起。

console.log("obj.__proto__.show(): "+obj.__proto__.show()); //obj.__proto__.show(): i am A
console.log("obj.x : "+obj.x);  //undefined   oh soga。这个是正常的,由于A中定义x是this.x="i am x"  x是A实例的属性,obj报undefined是正常的

  obj的__proto__可以调用show()方法,说明obj的__proto__确实指向A  

  关于第二个验证obj.x是多余的。obj 自己没有x属性,沿着原型链 obj的prototype Object.create()建立的父类也没有定义x。obj的prototype的prototype也就是A,A函数里面有x,可是A自己没有定义x因此报undefined是正常的。果真基础不够扎实,才写了这多余的验证。

  再随便看下原型链继承。

A.x="gg";
console.log("obj.x A have defined x : "+obj.x); //obj.x A have defined x : gg

  果真跟想的同样,obj没有x,它就需找它的父类(obj_father),父类没有定义this.x,注意这里是this.x 而不是父类.x(obj_father.x)。在父类中只有this.x才能被子类调用。父类.x是父类本身的私有属性。父类没有x因此找到父类的prototype即A。A有.x 因此就输入A的x。没有A没有就报undefined;

  就刚刚突发奇想 想看一下new一个实例对象会产生什么后果。

var b= new obj();//object is not a function 

  看到这个,我不得不嘲笑本身,原本就该这样,都不愿思考,还要写个程序验证!!!基础啊基础

  

  有理解不对的,但愿大牛指正,不胜感激。

相关文章
相关标签/搜索