我刚开始阅读this article并且我坚持第一段:
代码:
var foo = {x:10,y:20};
我们的结构有两个显式的自有属性和一个 隐式proto属性,它是对原型的引用 foo:
图1.带有原型的基本对象。
我的问题......
为什么图表显示基本对象文字的foo原型?
如果我创建两个对象,则表明情况并非如此: -
如果我使用调试器,它会显示对象1确实创建了一个One.prototype,它在链的下方还有一个Object.prototype,但是对象2没有一个two.prototype,而是直接进入Object.prototype中。
我是否误解了原型概念,或者文章不正确暗示对象文字有自己的原型?
编辑: 我放弃了阅读这篇文章,它破碎的英语使一个复杂的主题变得更加复杂。
this video中的那个人回答了我的问题并总结了一下:
答案 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。