17

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

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

Object.create(Object) returns a non empty object

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

Can't understand what is going on here

4

2 回答 2

28

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

Object.create创建对象。您给出的第一个参数Object.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";

这让我们记忆犹新:

                           +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+
                           | [[原型]] |−−−−−>| (标准 |
a−−−−−−−−−−−−−−−−−−−−−−−+−−>| 富:42 | | 对象原型)|
                       | +−−−−−−−−−−−−−−−−+ +−−−−−−−−−−−−−−−−−−−−−+   
                       |
    +−−−−−−−−−−−−−−−−+ |
b−−>| [[原型]] |−−+
    | 酒吧:“嗨”|
    +−−−−−−−−−−−−−−−−−+

证明b用途a

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

解决您的一些变化:

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

这与 完全相同var o = {};:它创建一个新的空白对象,其原型是对象Object.prototype引用。

var o = Object.create(Object);

这将创建一个新的空白对象o,其原型是Object函数。它不创建函数,只是一个以函数为原型的非函数对象。这会很奇怪,可能不是你想要的。:-)

var o = Object.create(null);

创建一个o原型为的新空白对象null。由于它的原型是null,它没有通常的Object.prototype东西,比如toStringandvalueOfhasOwnProperty。这有点不寻常,尽管它有一些用例,例如当您将对象用作字典/映射并且不希望这些属性名称出现误报时。(在 ES2015 [aka ES6] 中,另一个选项是使用Map。)


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

一个对象(我们称之为o)有一个原型对象,它继承了它的属性。(在 ES2015+ 中,您可以通过 访问该对象Object.getPrototypeOf。)prototype函数属性上的对象根本不一定是任何对象的原型。相反,它将new分配为通过使用该函数创建的任何对象的原型的对象。

示例在这里有所帮助。

function Foo() {
}

该函数Foo具有Foo.prototype引用对象的属性。该对象尚未用作任何东西的原型。它只是分配给prototypeFoo对象实例上调用的属性的对象。

var f = new Foo();

现在该对象被用作原型,具体来说,它是调用f创建的对象的原型new Foo

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

var f = new Foo();

...基本上是这样做的:

// 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);

正如我所说,这遗漏了一些细节,但希望它有助于弄清楚prototype函数的属性是什么......

于 2013-05-21T09:16:33.390 回答
2

返回的是一个对象。

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

Function是 Chrome 寻址对象的构造函数的名称。请参阅如何为 Chrome 开发工具中的自定义类计算 javascript 类名称?


这部分答案解决了@phenomnomnominal 在问题中的评论,解释了为什么创建的对象具有继承函数属性,例如call.

构造Object函数是一个函数,因此继承自Function原型:

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

因此,具有Object原型的对象也将通过原型链链接到函数原型:

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

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

于 2013-05-21T09:25:32.857 回答