Object.create(Object.prototype)、Object.create(Object)和Object.create(create)之间的区别

时间:2022-09-24 23:33:27

Which parameter should i pass for the first parent object from which others will inherit and which one is more efficient

我应该将哪个参数传递给其他对象继承的第一个父对象,哪个参数更有效

Object.create(Object.prototype)

Object.create(Object)

Object.create(null)  

Object.create(null) returns an empty object

create(null)返回一个空对象

Object.create(Object) returns a function why????( I checked my log and it says function...i used console.dir() )

Object.create(Object)返回一个函数为什么????(我查看了日志,上面写着函数……)我用console.dir())

Object.create(Object) returns a non empty object

Object.create(Object)返回一个非空对象。

How does this whole thing work ... I m more used to the Classname .prototype thing :(

这整件事是怎么回事……I m more used to the Classname .prototype thing:(

Can't understand what is going on here

不明白这是怎么回事吗

2 个解决方案

#1


20  

Preface: JavaScript uses prototypical inheritance, which means that an object can have (usually does have) a prototype behind it, which is another object. If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, and so on) to find it.

前言:JavaScript使用原型继承,这意味着一个对象可以(通常)拥有它背后的原型,也就是另一个对象。如果您试图从一个没有属性的对象中获取属性的值,JavaScript引擎会查找对象的原型(以及它的原型,等等)来找到它。

Object.create creates objects. The first argument you give Object.create is the object to use as the prototype of the object it creates. So:

对象。创建创建对象。你给对象的第一个参数。create是用来作为它创建的对象的原型的对象。所以:

// Create an object with a property 'foo'
var a = {
    foo: 42
};

// Create a blank object using `a` as its prototype
var b = Object.create(a);

// Give `b` a property of its own
b.bar = "hi";

That gives us this in memory:

这让我们想起

                           +---------------+      +-------------------+
                           | [[Prototype]] |----->| (the standard     |
a----------------------+-->| foo: 42       |      | object prototype) |
                       |   +---------------+      +-------------------+   
                       |
    +---------------+  |
b-->| [[Prototype]] |--+
    | bar: "hi"     |
    +---------------+

Proof b uses a:

证明b使用:

console.log(b.foo); // 42
a.foo = 67;
console.log(b.foo); // 67

Addressing some of your variations:

解决你的一些变化:

var o = Object.create(Object.prototype);

That's pointless, just use var o = {};, it does the same thing (creates a new blank object whose prototype is Object.prototype).

这毫无意义,只需使用var o ={};它做同样的事情(创建一个新的空对象,其原型是object .prototype)。

var o = Object.create(Object);

Creates a new blank object o whose prototype is the Object function. It doesn't create a function, just a non-function object that has a function as its prototype. This would be quite odd and probably isn't what you want.

创建一个新的空对象o,其原型是对象函数。它不是创建一个函数,而是一个非函数对象,它的原型有一个函数。这很奇怪,可能不是你想要的。

var o = Object.create(null);

Creates a new blank object o whose prototype is null. Since its prototype is null, it doesn't have the usual Object.prototype stuff, like toString and valueOf and hasOwnProperty. That's a bit unusual, although there are use cases for it, such as when you're using an object as a dictionary/map and don't want false positives for those property names. (In ES2015 [aka ES6] another option is to use Map instead.)

创建一个新的空对象o,其原型为空。因为它的原型是空的,所以它没有通常的对象。比如toString valueOf和hasOwnProperty。这有点不寻常,尽管有它的用例,比如当您使用对象作为字典/映射时,并且不希望这些属性名出现假阳性。(在ES2015年(又名ES6),另一个选择是使用Map。)


As thg435 points out in a comment below, one of the confusing things about JavaScript is that the prototype of an object is a completely different thing from the prototype property you see on functions. It would probably be better if the prototype property had had a different name (although I can't imagine what name it would be without being massively clunky).

正如thg435在下面的评论中指出的,关于JavaScript的一个令人困惑的事情是,对象的原型与函数上的原型属性完全不同。如果原型属性有一个不同的名字(尽管我无法想象它会是什么名字而不是非常笨拙),它可能会更好。

An object (let's call it o) has a prototype object it inherits properties from. The object on the prototype property of functions is not necessarily the prototype of any object at all. Instead, it's the object that will be assigned as the prototype of any object created via new using that function.

一个对象(我们叫它o)有一个原型对象,它继承了它的属性。函数的原型属性上的对象不一定是任何对象的原型。相反,这个对象将被分配为使用该函数通过新创建的任何对象的原型。

Examples help here.

这里的例子帮助。

function Foo() {
}

That function, Foo, has a property Foo.prototype that refers to an object. That object is not, yet, used as the prototype of anything. It's just an object assigned to a property called prototype on the Foo object instance.

这个函数Foo有一个属性Foo。指对象的原型。那个对象还没有被用作任何事物的原型。它只是一个对象,分配给Foo对象实例上的一个名为prototype的属性。

var f = new Foo();

Now that object is used as a prototype, specifically it's the prototype of the f object created by the new Foo call.

现在该对象被用作原型,特别是它是由新的Foo调用创建的f对象的原型。

Ignoring a couple of details, this line of code:

忽略一些细节,这行代码:

var f = new Foo();

...basically does this:

…基本上是这样的:

// Create a blank object, giving it `Foo.prototype` as its prototype
var f = Object.create(Foo.prototype);

// Call` Foo` using that new object as `this`
Foo.call(f);

As I say, that leaves out a couple of details, but hopefully it helps make it clear what the prototype property of functions is for...

正如我所说,这漏掉了一些细节,但希望它能帮助我们弄清楚函数的原型属性是用来做什么的。

#2


2  

What is being returned is an object.

返回的是一个对象。

>>> typeof Object.create(Object)
<<< "object"
>>> Object.create(Object)
<<< Function {}
//           ^^

Function is the name which Chrome addresses the object's constructor. See How are javascript class names calculated for custom classes in Chrome Dev Tools?

函数是Chrome用于对象构造函数的名称。查看如何在Chrome开发工具中计算定制类的javascript类名?


This part of the answer addresses @phenomnomnominal's comment in the question, explaining why the created object has inherits function properties such as call.

答案的这一部分将解决问题中的@ phenomnom标号的注释,解释为什么创建的对象继承了函数属性,如call。

The Object constructor is a function, and thus inherits from the Function prototype:

对象构造函数是一个函数,因此从函数原型继承:

>>> Object.call === Function.prototype.call
<<< true

So an object having Object as prototype will have a link to the Function prototype via prototype chain as well:

所以一个以对象为原型的对象也会通过原型链与功能原型联系起来:

>>> Object.create(Object).call === Function.prototype.call
<<< true

And as mentioned by @TJ, using a constructor as prototype is rather odd. You should specify an object as the prototype that the created object will inherit from. @TJ already did a pretty good job explaining this part.

正如@TJ提到的,使用构造函数作为原型是相当奇怪的。您应该指定一个对象作为创建对象将继承的原型。@TJ已经很好地解释了这个部分。

#1


20  

Preface: JavaScript uses prototypical inheritance, which means that an object can have (usually does have) a prototype behind it, which is another object. If you try to get the value of a property from an object that it doesn't have, the JavaScript engine looks to the object's prototype (and its prototype, and so on) to find it.

前言:JavaScript使用原型继承,这意味着一个对象可以(通常)拥有它背后的原型,也就是另一个对象。如果您试图从一个没有属性的对象中获取属性的值,JavaScript引擎会查找对象的原型(以及它的原型,等等)来找到它。

Object.create creates objects. The first argument you give Object.create is the object to use as the prototype of the object it creates. So:

对象。创建创建对象。你给对象的第一个参数。create是用来作为它创建的对象的原型的对象。所以:

// Create an object with a property 'foo'
var a = {
    foo: 42
};

// Create a blank object using `a` as its prototype
var b = Object.create(a);

// Give `b` a property of its own
b.bar = "hi";

That gives us this in memory:

这让我们想起

                           +---------------+      +-------------------+
                           | [[Prototype]] |----->| (the standard     |
a----------------------+-->| foo: 42       |      | object prototype) |
                       |   +---------------+      +-------------------+   
                       |
    +---------------+  |
b-->| [[Prototype]] |--+
    | bar: "hi"     |
    +---------------+

Proof b uses a:

证明b使用:

console.log(b.foo); // 42
a.foo = 67;
console.log(b.foo); // 67

Addressing some of your variations:

解决你的一些变化:

var o = Object.create(Object.prototype);

That's pointless, just use var o = {};, it does the same thing (creates a new blank object whose prototype is Object.prototype).

这毫无意义,只需使用var o ={};它做同样的事情(创建一个新的空对象,其原型是object .prototype)。

var o = Object.create(Object);

Creates a new blank object o whose prototype is the Object function. It doesn't create a function, just a non-function object that has a function as its prototype. This would be quite odd and probably isn't what you want.

创建一个新的空对象o,其原型是对象函数。它不是创建一个函数,而是一个非函数对象,它的原型有一个函数。这很奇怪,可能不是你想要的。

var o = Object.create(null);

Creates a new blank object o whose prototype is null. Since its prototype is null, it doesn't have the usual Object.prototype stuff, like toString and valueOf and hasOwnProperty. That's a bit unusual, although there are use cases for it, such as when you're using an object as a dictionary/map and don't want false positives for those property names. (In ES2015 [aka ES6] another option is to use Map instead.)

创建一个新的空对象o,其原型为空。因为它的原型是空的,所以它没有通常的对象。比如toString valueOf和hasOwnProperty。这有点不寻常,尽管有它的用例,比如当您使用对象作为字典/映射时,并且不希望这些属性名出现假阳性。(在ES2015年(又名ES6),另一个选择是使用Map。)


As thg435 points out in a comment below, one of the confusing things about JavaScript is that the prototype of an object is a completely different thing from the prototype property you see on functions. It would probably be better if the prototype property had had a different name (although I can't imagine what name it would be without being massively clunky).

正如thg435在下面的评论中指出的,关于JavaScript的一个令人困惑的事情是,对象的原型与函数上的原型属性完全不同。如果原型属性有一个不同的名字(尽管我无法想象它会是什么名字而不是非常笨拙),它可能会更好。

An object (let's call it o) has a prototype object it inherits properties from. The object on the prototype property of functions is not necessarily the prototype of any object at all. Instead, it's the object that will be assigned as the prototype of any object created via new using that function.

一个对象(我们叫它o)有一个原型对象,它继承了它的属性。函数的原型属性上的对象不一定是任何对象的原型。相反,这个对象将被分配为使用该函数通过新创建的任何对象的原型。

Examples help here.

这里的例子帮助。

function Foo() {
}

That function, Foo, has a property Foo.prototype that refers to an object. That object is not, yet, used as the prototype of anything. It's just an object assigned to a property called prototype on the Foo object instance.

这个函数Foo有一个属性Foo。指对象的原型。那个对象还没有被用作任何事物的原型。它只是一个对象,分配给Foo对象实例上的一个名为prototype的属性。

var f = new Foo();

Now that object is used as a prototype, specifically it's the prototype of the f object created by the new Foo call.

现在该对象被用作原型,特别是它是由新的Foo调用创建的f对象的原型。

Ignoring a couple of details, this line of code:

忽略一些细节,这行代码:

var f = new Foo();

...basically does this:

…基本上是这样的:

// Create a blank object, giving it `Foo.prototype` as its prototype
var f = Object.create(Foo.prototype);

// Call` Foo` using that new object as `this`
Foo.call(f);

As I say, that leaves out a couple of details, but hopefully it helps make it clear what the prototype property of functions is for...

正如我所说,这漏掉了一些细节,但希望它能帮助我们弄清楚函数的原型属性是用来做什么的。

#2


2  

What is being returned is an object.

返回的是一个对象。

>>> typeof Object.create(Object)
<<< "object"
>>> Object.create(Object)
<<< Function {}
//           ^^

Function is the name which Chrome addresses the object's constructor. See How are javascript class names calculated for custom classes in Chrome Dev Tools?

函数是Chrome用于对象构造函数的名称。查看如何在Chrome开发工具中计算定制类的javascript类名?


This part of the answer addresses @phenomnomnominal's comment in the question, explaining why the created object has inherits function properties such as call.

答案的这一部分将解决问题中的@ phenomnom标号的注释,解释为什么创建的对象继承了函数属性,如call。

The Object constructor is a function, and thus inherits from the Function prototype:

对象构造函数是一个函数,因此从函数原型继承:

>>> Object.call === Function.prototype.call
<<< true

So an object having Object as prototype will have a link to the Function prototype via prototype chain as well:

所以一个以对象为原型的对象也会通过原型链与功能原型联系起来:

>>> Object.create(Object).call === Function.prototype.call
<<< true

And as mentioned by @TJ, using a constructor as prototype is rather odd. You should specify an object as the prototype that the created object will inherit from. @TJ already did a pretty good job explaining this part.

正如@TJ提到的,使用构造函数作为原型是相当奇怪的。您应该指定一个对象作为创建对象将继承的原型。@TJ已经很好地解释了这个部分。