关于第一个参数对Object.create()结果造成的不同的一个小疑惑


代码如图: 图片描述

我们都知道Object.create()方法的第一个参数是创建出来的新对象的原型,但当我试图用一个函数a作为新对象的原型、和用函数a的原型对象作为新对象的原型时,却发现了一些疑惑。

首先,当我们将函数a作为新对象的原型时,函数a上的静态方法,被新创建出来的对象b所继承,这点没有疑问。
当我们用函数a的原型对象作为新对象的原型时,函数a的原型对象上的一些方法,被新创建出来的对象b所继承,这点也没有疑问。

疑问来了,为什么两者所造出来的新对象b,前者拥有prototype属性,而后者却没有prototype属性。前者造出来的新对象b的构造函数是function Function(){},而后者的表现就和new a()后新创建一个对象b表现大多相同的,但为什么却没有name属性。

希望前辈们可以帮我解解惑,谢谢

web web前端开发 前端 JavaScript 前端开发

l2y3n2 9 years, 10 months ago

clipboard.png
不知道你明白这个图的意思不。。


 b.__proto__ == a.prototype

乃心明眼亮 answered 9 years, 10 months ago

我依次给题主解释一下你敲的那些代码示例。
首先是作为前提,解释一下Object.create,这个函数实际上是把里面的第一个参数作为返回值的原型,通俗的说法就是下面两个实际上是等价的:


 javascript


 var b = Object.create(a);
//等价于下面这个
b.__proto__ = a;

这个前提理解了以后,下面解释下左边部分。
b.say这个方法,由于b对象没有say方法,原型链发生作用,它会从b的原型上寻找,这个时候b.say实际上是调用 b.__proto__.say ,又因为 b.__proto__ 等于a,也就是调用a.say

b.prototype ,这个b当然也没有prototype属性,所以实际上也是调用 b.__proto__.prototype

b.constructor也就是 b.__proto__.constructor ,也就是a.constructor,你直接声明定义的a,构造函数是Function()

b.constructor.prototype 也就是 b.__proto__.constructor.prototype ,也就是a.constructor.prototype,是个Empty()

========================

右半部分
根据上面Object.create的解释你应该明白此时就是 b.__proto__ = a.prototype

所以


 javascript


 b.say === b.__proto__.say === a.prototype.say

b.prototype === b.__proto__.prototype ===  a.prototype.prototype  === undefined

b.constructor  === b.__proto__.constructor ===  a.prototype.constructor === a

b.constructor.prototype === b.__proto__.constructor.prototype === a.prototype.constructor.prototype === a.prototype

是不是明白了?

所以ES5的类继承写法一般是这样的


 javascript


 function A(){}
function B(){}

B.prototype = Object.create(A.prototype);
B.prototype.constructor = B;

//相当于 B.prototype.__proto__ = A.prototype

NG-KING answered 9 years, 10 months ago

Your Answer