__proto__:函数声明与对象文字

时间:2014-04-23 14:36:10

标签: javascript prototype

我刚开始阅读this article并且我坚持第一段:

  

代码:

     

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

     

我们的结构有两个显式的自有属性和一个   隐式proto属性,它是对原型的引用   foo:

enter image description here

  

图1.带有原型的基本对象。

我的问题......

为什么图表显示基本对象文字的foo原型?

如果我创建两个对象,则表明情况并非如此: -

  • 对象一 - 函数对象/构造函数
  • 对象二 - 具有键/值对的基本对象文字,如字典

如果我使用调试器,它会显示对象1确实创建了一个One.prototype,它在链的下方还有一个Object.prototype,但是对象2没有一个two.prototype,而是直接进入Object.prototype中。

enter image description here

我是否误解了原型概念,或者文章不正确暗示对象文字有自己的原型?


编辑: 我放弃了阅读这篇文章,它破碎的英语使一个复杂的主题变得更加复杂。

this video中的那个人回答了我的问题并总结了一下:

  • 每个对象都有__ proto __
  • 只有函数有原型
  • prototype是使用new运算符时使用的模板

2 个答案:

答案 0 :(得分:3)

__proto__来自构造函数prototype

在第一种情况下,One是您的构造函数。您尚未为One.prototype分配任何内容,因此默认为Object __proto__,您可以获得两个级别的继承。

如果您向该对象添加了内容,它们将显示为One原型的一部分。

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

var one = new One();

在第二种情况下,您正在创建一个具有Object原型的对象文字,因此您只能继承Object原型。原型本身就是对象,所以如果你要添加属性,就像这样:

foo.__proto__.z = 'foobar';

您正在修改foo原型的Object实例,它不会修改Object本身,只修改它的特定实例。这就是文章的意思,foo的原型。

我刚刚在V8中进行了测试,似乎对象文字没有Object的实例作为它的原型,它有Object' s __proto__本身,因此您不应修改foo.__proto__,您将修改所有对象继承的基础Object原型。如果您希望对其进行修改,则应首先创建Object的新实例以添加到:

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

示例:

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'

在我看来,如果对象文字自动为__proto__创建了一个新的Object实例,那会更好。再说一次,没有理由修改对象文字的原型。

另请注意,您不应直接使用__proto__,因为它已弃用,其未来的替换为strongly discouraged as well。您应该使用Object.create在Javascript中实现继承。

答案 1 :(得分:1)

JavaScript中有两个相互关联的原型概念:

首先,每个JavaScript函数都有一个prototype属性(默认情况下它是空的),并且当你想要实现继承时,你可以在这个prototype属性上附加属性和方法。注意这个prototype属性不可枚举:在for / in循环中无法访问它。但Firefox和大多数版本的Safari和Chrome都有__ proto__“伪”属性(另一种方式),允许您访问对象的原型属性。你可能永远不会使用这个__ proto__伪属性,但知道它存在,它只是一种在某些浏览器中访问对象的prototype属性的方法。 prototype属性主要用于继承:在函数的prototype属性上添加方法和属性,以使这些方法和属性可用于该函数的实例。

JavaScript中的原型第二个概念是原型属性。将prototype属性视为对象的特征;这个特征告诉我们对象的“父母”。简单来说:对象的prototype属性指向对象的“父” - 它从中继承其属性的对象。 prototype属性通常被称为原型对象,它在您创建新对象时自动设置。对此进行阐述:每个对象都从其他对象继承属性,而另一个对象是对象的原型属性或“父母。”(您可以将原型属性视为血统或父母)。在上面的示例代码中,newObj的原型是PrintStuff.prototype。