ECMAScript 6支持可变的__proto__属性吗?

6
在当前的Ecmascript 6草案(2012年11月)中,官方支持__proto__属性(第B.3.1节)。这有点令人惊讶,因为在当前的浏览器实现中,__proto__属性已被弃用。
如果当前的草案得以通过,ES6是否会完全支持可变原型?我是否能够像在Firefox中一样为现有对象提供新原型?

__proto__ 属性已经被“废弃”,因为它不是标准属性,建议使用 Object.getPrototypeOf(someObject);(ECMA5 标准,因此支持跨浏览器)。除此之外,在运行时更改原型并不是什么新鲜事物:我在 Chrome 和 IE 中尝试将自定义对象的原型更改为 new Array,没有任何问题... 这只是原型模型固有的特性。 - Elias Van Ootegem
@Elias。Object.getPrototypeOf()是Ecmascript 5的功能,因为__proto__从未成为Ecmascript标准的一部分。似乎__proto__首先从浏览器中弃用,然后(第一次)引入了标准。虽然这种事件顺序看起来不寻常,但情况似乎是如此。我特别询问Ecmascript 6-B.3.1中的“new”__proto__。 - Jack Wester
我不确定你在问什么。它在当前草稿中,所以是的,看起来我们会有那个。另一方面,它仍然是一个草稿,所以任何事情都可能改变。 - bfavaretto
@bfavaretto - 问题是ES6的__proto__是否提供与旧版本相同的可变行为。也就是说,这是否是在某些浏览器中发现的被认为已经死亡的__proto__实现的完全复活。 - Jack Wester
2
除了@benvie的精彩回答之外,还要注意当前草案中存在可变的[[Prototype]],即Reflect.setPrototypeOf。关于它被错误地放置的讨论已经进行了一段时间,听起来__proto__最终会被使用,但目前仍有些不确定。 - Nathan Wall
2个回答

9

目前,计划将可变的__proto__列入规范中(而不仅仅是在附录B中)。当前的计划是将其作为Object.prototype上存在的神奇数据属性并充当访问器(其中包含神奇部分)。此属性也可删除,删除时将删除该域的__proto__的变异能力。我已按照这个描述在我的ES6虚拟机http://benvie.github.com/continuum中实现了__proto__

最初它曾被弃用并被替换,但没有形成一致意见。从内置对象继承的能力是最终目标,决定是__proto__已经广泛使用(除了IE之外),并实现了这个目标,所以最省力的方法是采纳和编码它。


1
刚才开始用它了,哇,太疯狂了! - Ven
1
这个答案似乎已经过时了。看起来Reflect.setPrototypeOf已经成为替代方案的共识,而__proto__仍然在Web遗留Annex B中,没有移动的计划。 - Bergi
根据http://webreflection.blogspot.com/2013/05/objectsetprototypeofo-proto-is-in-es6.html的说法,在ES6中官方的方法是使用`Object.setPrototypeOf`。 - Matt Browne

2
根据发布的Ecmascript 6文档,__proto__仍然存在,但正如BergiMattBrowne在上面的解决方案中指出的那样,我们可以使用Object.setPrototypeOf,这是__proto__的修改版本。
当使用参数 O 和 proto 调用 setPrototypeOf 函数时,将执行以下步骤:
  • 让 O 成为 RequireObjectCoercible(O)。
  • 如果出现异常,返回它。
  • 如果 proto 的类型既不是 Object 也不是 Null,则抛出 TypeError 异常。
  • 如果 O 的类型不是 Object,则返回 O。
  • 让状态成为 O.[SetPrototypeOf]。
  • 如果出现异常,返回它。
  • 如果状态为 false,则抛出 TypeError 异常。
  • 返回 O。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接