简体   繁体   English

JavaScript -- null 或 Object.prototype 中原型链的结尾是什么?

[英]What is the end of prototype chain in JavaScript -- null or Object.prototype?

I've been reading about the prototype chain in JavaScript and came to two slightly different definitions.我一直在阅读 JavaScript 中关于原型链的内容,得出了两个略有不同的定义。 It is said that every object in JavaScript has a prototype and that prototype in turn has another prototype.据说 JavaScript 中的每个 object 都有一个原型,而这个原型又有另一个原型。

The top prototype (Grand) may also have prototype and the chain can continue.顶层原型(Grand)也可能有原型,链条可以继续。 Now the chain will stop at one last object. JavaScript: The Good Parts says the chain terminates at Object.prototype and MDN says null is the final link where the chain terminates.现在链将在最后一个 object 处停止。 JavaScript:Good Parts说链在Object.prototype处终止, MDN 说null是链终止的最后一个链接。

Javascript: The Good Parts Javascript:好的部分

Every object is linked to a prototype object from which it can inherit properties.每个 object 都链接到原型 object,它可以从原型继承属性。 All objects created from object literals are linked to Object.prototype , an object that comes standard with JavaScript.从 object 文字创建的所有对象都链接到Object.prototype ,一个 object 是 JavaScript 的标准配置。


MDN MDN

Each object has an internal link to another object called its prototype.每个 object 都有一个到另一个 object 的内部链接,称为其原型。 That prototype object has a prototype of its own, and so on until an object is reached with null as its prototype.该原型 object 有自己的原型,依此类推,直到以 null 为原型到达 object。 null, by definition, has no prototype, and acts as the final link in this prototype chain . null,根据定义,没有原型,作为这个原型链的最后一环

  • What is the end of prototype chain in JavaScript -- null or Object.prototype? JavaScript -- null 或 Object.prototype 中原型链的结尾是什么? Or are null and Object.prototype one and the same thing?或者nullObject.prototype是一回事吗?
  • Are objects, which are not created from object literals, not linked to Object.prototype ?不是从 object 文字创建的对象是否未链接到Object.prototype
  • Say I have an object var x = { len: 4, breadth: 5} .假设我有一个 object var x = { len: 4, breadth: 5} Would JavaScript automatically create its prototype x.prototype ? JavaScript 会自动创建其原型x.prototype吗? And how long would the prototype chain be?原型链有多长? Would x.prototype have only one prototype, Object.prototype , making a 3 point chain? x.prototype是否只有一个原型Object.prototype ,构成一个 3 点链?
  • How does JavaScript internally create automatic prototypes? JavaScript内部是如何创建自动原型的?

What is the end of prototype chain in javascript javascript中的原型链的末尾是什么

Null. 空值。 The only authority on the language is ECMA-262 . 该语言的唯一授权机构是ECMA-262

Are objects, which are not created from object literals, not linked to Object.prototype 是不是从对象文字创建的,未链接到Object.prototype的对象

They may or many not be, eg 它们可能是,也可能不是,例如

var x = Object.create(null)

has a [[Prototype]] of null, whereas: [[Prototype]]为null,而:

var y = {};

has a [[Prototype]] of Object.prototype. 具有Object.prototype的[[Prototype]]

Say I have an object var x = { len: 4, breadth: 5}. 假设我有一个对象var x = {len:4,广度:5}。 Would javascript automatically create it's proptotype x.prototype. javascript会自动创建它的原型x.prototype。

No. Function objects have default prototype objects. 否。功能对象具有默认的原型对象。 Plain objects have a default [[Prototype]] (ie internal prototype property) that is Object.prototype (unless constructed as above). 普通对象具有默认的[[Prototype]] (即内部原型属性),即Object.prototype (除非如上所述构造)。

And how long would the prototype chain be? 原型链将持续多久? Would x.prototype have only one prototype Object.prototype making a 3 point chain? x.prototype是否只有一个原型Object.prototype构成3点链?

Two values: Object.prototype and null . 两个值: Object.prototypenull

How does javascript internally creates automatic prototypes? javascript如何在内部创建自动原型?

However it likes, the language specification does not define implementation, only behaviour. 但是,它喜欢语言规范不定义实现,而仅定义行为。

  1. It is like, if New York has an envelop and inside, it says Colorado, and Colorado has an envelop, and inside, it says San Francisco, and San Francisco has an envelop, and inside, it says "none". 就像,如果纽约有一个信封,里面说科罗拉多,而科罗拉多有一个信封,里面说旧金山,而旧金山有信封,里面说“无”。 So is San Francisco end of the chain, or is "none" the end of chain? 那么,旧金山是链的尽头,还是“没有”链的尽头? It may depend on how you look at it. 这可能取决于您如何看待它。 But one thing is for sure: it points up and up the chain, for inheritance purpose (prototypal inheritance), until it reaches null , which means can't go further up. 但是有一点是肯定的:出于继承(原型继承)的目的,它向上和向上指向链,直到达到null ,这意味着无法进一步发展。 And make sure you know that, to go up and up the chain, it is __proto__ . 并确保您知道,要沿链向上移动,它是__proto__ It is not prototype . 它不是prototype

  2. Object.prototype , Animal.prototype are different from x.__proto__ . Object.prototypeAnimal.prototypex.__proto__不同。 The former are function objects (Object, Animal) having a prototype property pointing to a prototype object. 前者是具有指向原型对象的prototype属性的函数对象(对象,动物)。 And x.__proto__ is how the prototype chain is followed upward. x.__proto__是原型链如何向上跟随的方式。 To go up and up, it is x.__proto__.__proto__ and so on. x.__proto__.__proto__上升,它是x.__proto__.__proto__等等。 See JavaScript's Pseudo Classical Inheritance diagram to understand it more. 请参阅JavaScript的Pseudo经典继承图以了解更多信息。

  3. Object.prototype refers to a prototype object. Object.prototype是指原型对象。 Quoted from MDN , null "represents the intentional absence of any object value. It is one of JavaScript's primitive values." 引用自MDN的 null表示有意缺少任何对象值。它是JavaScript的原始值之一。 So Object.prototype and null are not the same thing. 因此, Object.prototypenull不是同一件事。

  4. All JavaScript objects will have obj.__proto__ referring ultimately to what Object.prototype refers to. 所有JavaScript对象的obj.__proto__最终都将引用Object.prototype引用的内容。 If it is not obj.__proto__ , then it is obj.__proto__.__proto__ . 如果不是obj.__proto__ ,则为obj.__proto__.__proto__ If not, just go up, and up, and it will reach the prototype object which Object.prototype refers to. 如果不是,则向上然后向上,它将到达Object.prototype引用的原型对象。 And at this point, when you go up one level (by adding a .__proto__ , then you get null . You can try it in Google Chrome's developer's tool: 至此,当您上一层时(通过添加.__proto__ ,您将获得null 。您可以在Google Chrome开发人员的工具中尝试使用它:

     x = { a : 1 } > Object {a: 1} x.__proto__ === Object.prototype > true x.__proto__.__proto__ > null Object.prototype.__proto__ > null 

What is the end of prototype chain in javascript -- null or Object.prototype ? javascript中的原型链的末尾是什么? nullObject.prototype Or are null and Object.prototype one and the same thing? 还是null和Object.prototype是一回事?

null . null Consider this code in a normal JavaScript environment: 在正常的JavaScript环境中考虑以下代码:

var o = {};
console.log(o.i_am_a_property_that_does_not_exist);

That property accessor operation ( o.i_am_a_property_that_does_not_exist ) ends up going to the OrdinaryGet abstract operation defined by the specification with O set to the o object above and P set to "i_am_a_property_that_does_not_exist" . 该属性访问器操作( o.i_am_a_property_that_does_not_exist )最终转到规范定义的OrdinaryGet抽象操作,其中O设置为上述o对象, P设置为"i_am_a_property_that_does_not_exist" That operation starts like this: 该操作开始如下:

  1. Assert: IsPropertyKey( P ) is true. 断言:IsPropertyKey( P )为true。
  2. Let desc be ? desc为? O .[GetOwnProperty]. O。 [GetOwnProperty]。
  3. If desc is undefined , then 如果descundefined ,则

    a. 一种。 Let parent be ? 父母成为? O .[GetPrototypeOf]. O。 [GetPrototypeOf]。

    b. b。 If parent is null , return undefined . 如果parentnull ,则返回undefined

    c. C。 Return ? 返回? parent .[[Get]]( P , Receiver ). 父项 。[[获取]]( P接收器 )。

  4. ... ...

For my example above, that [[Get]] operation in 3.c. 对于我上面的示例,3.c中的[[Get]]操作。 ends up calling OrdinaryGet recursively until we run out of prototypes. 最终递归地调用OrdinaryGet,直到我们用完原型为止。 As we can see, the chain ends when we reach null . 如我们所见,当到达null时,链结束。

Moreover, it's entirely possible to have an object with a prototype chain that doesn't include Object.prototype at all (we'll see some in a moment). 而且,完全有可能使对象的原型链根本不包含Object.prototype (我们稍后会看到)。 So clearly Object.prototype can't be the end of the prototype chain. 显然, Object.prototype不能成为原型链的终点。

Are objects, which are not created from object literals, not linked to Object.prototype ? 不是从对象文字创建的对象是否未链接到Object.prototype

The vast majority will be linked to Object.prototype directly or indirectly. 绝大多数将直接或间接链接到Object.prototype Consider: 考虑:

function Thing() {
}
var t = new Thing();

t 's prototype is the object referenced by Thing.prototype . t的原型是Thing.prototype引用的对象。 Thing.prototype 's prototype is Object.prototype . Thing.prototype的原型是Object.prototype So t is linked to Object.prototype (indirectly). 所以t链接到Object.prototype (间接)。

But it's entirely possible for an object not to be linked to Object.prototype . 但是,对象完全可能链接到Object.prototype Here's one way: 这是一种方法:

var o = Object.create(null);

Object.create lets us create an object with the prototype we specify in the first argument ( null in the above). Object.create允许我们使用在第一个参数中指定的原型创建对象(上面为null )。 So o above has no prototype, its [[Prototype]] internal slot (where objects remember their prototypes) is null . 因此, o以上没有原型,其[[Prototype]]内部插槽(对象记住其原型的位置)为null

Here's another: 这是另一个:

function Thing() {
}
Thing.prototype = Object.create(null);
var t = new Thing();

In that case, although t has a prototype, its prototype's prototype is null; 在这种情况下,尽管t具有原型,但其原型的原型为null; t isn't linked to Object.prototype at all. t根本没有链接到Object.prototype

Say I have an object var x = { len: 4, breadth: 5} . 假设我有一个对象var x = { len: 4, breadth: 5} Would JavaScript automatically create it's prototype x.prototype . JavaScript是否会自动创建其原型x.prototype

An object's prototype is not a property called prototype , so no, the JavaScript engine wouldn't create x.prototype . 对象的原型不是称为prototype的属性,因此,JavaScript引擎不会创建x.prototype An object's prototype is linked via its [[Prototype]] internal slot, which is not directly observable but can be retrieved via Object.getPrototypeOf . 对象的原型通过其[[Prototype]]内部插槽进行链接,该内部插槽无法直接观察,但可以通过Object.getPrototypeOf进行检索。 (And if the object derives from Object.prototype , then on browsers only [in theory], you can use the Annex B [browser-only] __proto__ property from Object.prototype to access it. But not all objects have that property, because...not all objects inherit from Object.prototype !) (如果对象是从Object.prototype派生的,则仅在浏览器上[理论上],您可以使用Object.prototypeAnnex B [仅浏览器] __proto__属性进行访问。但是并非所有对象都具有该属性,因为...并非所有对象都继承自Object.prototype !)

The prototype property is just used on functions to determine what object to use as the [[Prototype]] of new objects created via new with that function. prototype属性只是用来上的功能确定为使用什么对象的[[原型]]的通过创建新对象new的具有该功能。 Non-function objects don't have it, and if they did, it wouldn't be any more special than a property called foo or bazinga . 非功能对象没有它,如果有的话,它不会比叫做foobazinga的属性更特别。

And how long would the prototype chain be? 原型链将持续多久? Would x.prototype have only one prototype Object.prototype making a 3 point chain? x.prototype是否只有一个原型Object.prototype构成3点链?

You're close, but again, the prototype property is not the prototype of the object, and non-function objects typically won't have a prototype property. 您接近了,但是, prototype属性不是对象的原型,非功能对象通常没有prototype属性。 For var x = { len: 4, breadth: 5} , the inheritance chain would be: 对于var x = { len: 4, breadth: 5} ,继承链为:

  • x
  • x 's [[Prototype]] (which is Object.prototype ) x的[[Prototype]](这是Object.prototype
  • Object.prototype 's [[Prototype]], which is null Object.prototype的[[Prototype]],为null

So quite short; 太短了; 1, 2, or 3 depending on whether you want to count x and whether you want to count null . 1、2或3取决于您是否要对x进行计数以及是否要对null进行计数。

How does JavaScript internally creates automatic prototypes? JavaScript如何在内部创建自动原型?

It doesn't, other than the ones defined by the spec (eg, Object.prototype and such). 除了规范所定义的以外(例如Object.prototype等),它没有。 The closest it comes is that for all function functions, the JavaScript engine automatically creates an object and assigns that object to the function's prototype property just in case that function is used as a constructor (via new ). 最接近的是,对于所有function函数,JavaScript引擎会自动创建一个对象,并将该对象分配给函数的prototype属性,以防万一该函数用作构造函数(通过new )。 (It doesn't do this with arrow functions or generators.) (它不使用箭头函数或生成器执行此操作。)

In the browser's console, try creating an object literal:在浏览器的控制台中,尝试创建一个 object 文字:

const myObject = 
{
  city: 'Madrid',
  greet() 
  {
    console.log(`Greetings from ${this.city}`);
  }
}

myObject.greet(); // Greetings from Madrid

This is an object with one data property, city , and one method, greet() .这是一个 object,具有一个数据属性city和一个方法greet()

If you type the object's name followed by a period into the console, like myObject.如果您在控制台中键入对象名称后跟一个句点,例如myObject. , then the console will pop up a list of all the properties available to this object. , 然后控制台会弹出这个 object 可用的所有属性的列表。

You'll see that as well as city and greet, there are lots of other properties!您会看到,除了 city and greet 之外,还有许多其他属性!

__defineGetter__
__defineSetter__
__lookupGetter__
__lookupSetter__
__proto__
city
constructor
greet
hasOwnProperty
isPrototypeOf
propertyIsEnumerable
toLocaleString
toString
toValueOf

Try accessing one of them:尝试访问其中之一:

myObject.toString(); // "[object Object]"

Copy to Clipboard复制到剪贴板

It works (even if it's not obvious what toString() does).它有效(即使toString()的作用并不明显)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM