简体   繁体   English

__proto__:函数声明与对象常量

[英]__proto__ : function declaration versus object literal

I've just started reading this article and I'm stuck on the first paragraph: 我刚刚开始阅读这篇文章 ,现在只停留在第一段:

For the code: 对于代码:

var foo = { x: 10, y: 20 }; var foo = {x:10,y:20};

we have the structure with two explicit own properties and one implicit proto property, which is the reference to the prototype of foo: 我们具有两个显式自己的属性和一个隐式原型属性的结构,这是对foo原型的引用:

在此处输入图片说明

Figure 1. A basic object with a prototype. 图1.具有原型的基本对象。

My question... 我的问题...

Why does the diagram show a foo prototype for a basic object literal? 为什么该图显示基本对象文字的foo原型

If I create two objects, it shows this isn't the case:- 如果我创建两个对象,则表明情况并非如此:-

  • object one - a function object / constructor function 对象一-函数对象/构造函数
  • object two - a basic object literal with key/value pairs like a dictionary 对象2-具有键/值对的基本对象文字,如字典

If I use the debugger, it shows that object one does indeed create a One.prototype which also has an Object.prototype further down the chain, but object two does not have a two.prototype, instead it goes straight to the Object.prototype. 如果我使用调试器,则表明对象确实确实创建了一个One.prototype,该对象在链的更下方也具有Object.prototype,但是对象2没有two.prototype,而是直接转到Object.prototype。 。

在此处输入图片说明

Have i misunderstood the proto concept or is the article incorrect by implying object literals have their own prototype? 我是否误解了原型概念,还是通过暗示对象字面量具有自己的原型来使本文错误?


EDIT: I've given up reading the article, it's broken English makes a complicated subject more complicated. 编辑:我已经放弃阅读文章,因为英语的破译使复杂的话题变得更加复杂。

The guy in this video answers my question and to sum it up: 视频中的那个人回答了我的问题,并总结了一下:

  • every object has a __ proto __ 每个对象都有一个__原型__
  • only functions have a prototype 只有功能才有原型
  • prototype is the template used when using new operator 原型是使用new运算符时使用的模板

The __proto__ comes from the constructor's prototype . __proto__来自构造函数的prototype

In the first case, One is your constructor. 在第一种情况下, One是您的构造函数。 You haven't assigned anything to One.prototype , so it defaults to a Object 's __proto__ and you get the two levels of inheritance. 您尚未为One.prototype分配任何One.prototype ,因此它默认为Object__proto__ ,您将获得两个继承级别。

If you had added things to that object, they would show up as part of the One prototype. 如果您向该对象添加了东西,它们将显示为One原型的一部分。

function One() {
  this.x = 4;
  this.y = 'hhh';
}
One.prototype.z = 'foobar';

var one = new One();

In the second case, you are creating an object literal which has Object as it's prototype, so you only inherit from the Object prototype. 在第二种情况下,您将创建一个对象文字,该对象文字具有Object作为原型,因此您只能从Object原型继承。 Prototypes are objects themselves, so if you were to add properties to it, like so: 原型本身就是对象,因此,如果要向其添加属性,如下所示:

foo.__proto__.z = 'foobar';

You are modifying the instance of Object that is foo 's prototype, it doesn't modify Object itself, only that particular instance of it. 您正在修改的是foo原型的Object实例,它不会修改Object本身,而只会修改Object特定实例。 That is what the article means, by foo 's prototype. 这就是foo原型的含义。

I just did a test in V8 and it seems an object literal doesn't have an instance of Object as it's prototype, it has Object 's __proto__ itself, so you should not modify foo.__proto__ , you would be modifying the underlying Object prototype that all Objects inherit from. 我刚刚在V8中进行了测试,似乎对象文字没有原型的Object实例,它本身具有Object__proto__ ,因此您不应该修改foo.__proto__ ,而是要修改基础的Object原型。所有对象都继承自该对象。 If you do wish do modify it, you should create a new instance of Object first to add to: 如果希望修改它,则应首先创建一个新的Object实例,然后添加到:

foo.__proto__ = {};
foo.__proto__.z = 'foobar';

Example: 例:

var x = {};
x.__proto__ = {};
x.__proto__.z = 'foobar';
var y = {};
y.z; // undefined
Object.z; // undefined

vs.

var x = {};
x.__proto__.z = 'foobar';
var y = {};
y.z; // 'foobar'
Object.z; // 'foobar'

In my opinion, it would be better if object literals automatically created a new instance of Object for their __proto__ . 我认为,如果对象文字为它们的__proto__自动创建Object的新实例会更好。 Then again, there is no real reason in modifying the prototype of an object literal. 再说一次,没有真正的理由来修改对象文字的原型。

Also note that you should not use __proto__ directly, as it is deprecated, and its future replacement is strongly discouraged as well . 还要注意,您不应该直接使用__proto__ ,因为它已被弃用,并且强烈建议不要将来使用它。 You should use Object.create for implementing inheritance in Javascript. 您应该使用Object.create在Javascript中实现继承。

There are two interrelated concepts with prototype in JavaScript: JavaScript中的原型有两个相互关联的概念:

First , there is a prototype property that every JavaScript function has (it is empty by default), and you attach properties and methods on this prototype property when you want to implement inheritance.Note that this prototype property is not enumerable: it is not accessible in a for/in loop. 首先 ,每个JavaScript函数都有一个原型属性(默认情况下为空),并且在您想要实现继承时将属性和方法附加到该原型属性上。请注意,该原型属性不可枚举:不可访问在for / in循环中。 But Firefox, and most versions of Safari and Chrome, have a __ proto__ “pseudo” property (an alternative way) that allows you to access an object's prototype property. 但是Firefox以及大多数Safari和Chrome版本都具有__proto __“ pseudo”属性(另一种方式),可让您访问对象的prototype属性。 You will likely never use this __ proto__ pseudo property, but know that it exists and it is simply a way to access an object's prototype property in some browsers. 您可能永远不会使用此__ proto__伪属性,但知道它存在,这只是在某些浏览器中访问对象的prototype属性的一种方式。 The prototype property is used primarily for inheritance: you add methods and properties on a function's prototype property to make those methods and properties available to instances of that function. prototype属性主要用于继承:您可以在函数的prototype属性上添加方法和属性,以使这些方法和属性可用于该函数的实例。

The second concept with prototype in JavaScript is the prototype attribute. JavaScript中带有原型的第二个概念是prototype属性。 Think of the prototype attribute as a characteristic of the object; 将原型属性视为对象的特征; this characteristic tells us the object's “parent”. 这个特征告诉我们物体的“父母”。 In simple terms: An object's prototype attribute points to the object's “parent”—the object it inherited its properties from. 简而言之:对象的原型属性指向对象的“父对象”,即从其继承其属性的对象。 The prototype attribute is normally referred to as the prototype object, and it is set automatically when you create a new object.To expound on this: Every object inherits properties from some other object, and it is this other object that is the object's prototype attribute or “parent.” (You can think of the prototype attribute as the lineage or the parent). 原型属性通常称为原型对象,在创建新对象时会自动设置。详细说明:每个对象都继承其他对象的属性,而另一个对象就是该对象的原型属性。或“父代”。(您可以将prototype属性视为血统或父代)。 In the example code above, newObj's prototype is PrintStuff.prototype. 在上面的示例代码中,newObj的原型是PrintStuff.prototype。

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

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