如何设置已经实例化的JavaScript对象的原型?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (41)

假设我的fooJavaScript代码中有一个对象。 foo是一个复杂的对象,它是在其他地方生成的。我怎样才能改变foo物体的原型?

我的动机是将适当的原型设置为从.NET到JavaScript文字序列化的对象。

假设我在ASP.NET页面中编写了以下JavaScript代码。

var foo = <%=MyData %>;

假设这MyDataJavaScriptSerializer在一个Dictionary<string,string>对象上调用.NET的结果。

在运行时,这变成以下内容:

var foo = [{"A":"1","B":"2"},{"X":"7","Y":"8"}];

正如你所看到的,foo成为一个对象数组。我希望能够foo用适当的原型进行初始化。我不是要修改Object.prototype,也没有Array.prototype。我怎样才能做到这一点?

提问于
用户回答回答于

__proto__被添加到ECMAScript 6作为“规范可选”,这意味着它不需要实现,但如果是,它必须遵循给定的规则集。这目前尚未解决,但至少它将正式成为JavaScript规范的一部分。

这个问题比表面上看起来要复杂得多,并且超出了大多数人对Javascript内部知识的薪酬等级。

prototype创建该对象的新的子对象时,对象的属性使用。改变它并不反映在对象本身中,而是反映在对象被用作其他对象的构造函数时,并且没有用于更改现有对象的原型。

function myFactory(){};
myFactory.prototype = someOtherObject;

var newChild = new myFactory;
newChild.__proto__ === myFactory.prototype === someOtherObject; //true

对象具有指向当前原型的内部[[prototype]]属性。它的工作方式是每当一个对象的属性被调用时,它将从对象开始,然后遍历[[prototype]]链直到它找到匹配,或者在根对象原型之后失败。这是Javascript允许运行时构建和修改对象的方式; 它有一个寻找它需要的计划。

__proto__属性存在于一些实现中(现在很多):任何Mozilla实现,我知道的所有webkit,以及其他一些实现。此属性指向内部[[prototype]]属性,并允许在对象上进行修改后创建。由于这种链式查找,任何属性和功能都会立即切换到匹配原型。

此功能虽然现在已经标准化,但仍不是JavaScript的必需部分,支持它的语言极有可能将您的代码敲入“未优化”类别。JS引擎必须尽最大努力对代码进行分类,特别是经常访问的“热门”代码,如果你喜欢修改某些东西,__proto__他们根本不会优化你的代码。

这篇文章https://bugzilla.mozilla.org/show_bug.cgi?id=607863特别讨论__proto__了它们之间的当前实现和差异。每个实现都有所不同,因为这是一个难以解决的问题。JavaScript中的所有东西都是可变的,除了a。)语法b。)宿主对象(DOM在技术上存在于Javascript之外)和c。)__proto__。其余的完全掌握在你和其他开发者的手中,所以你可以看到为什么会__proto__像拇指一样伸出手。

有一件事情是__proto__不允许的:在运行时指定一个对象原型,与其构造函数分开。这是一个重要的用例,而且其中一个主要原因__proto__还没有死。重要的是它已经成为Harmony的一个严肃的讨论点,或者很快被称为ECMAScript 6.在创建过程中指定对象的原型的能力将成为下一个Javascript版本的一部分,这将是指示__proto__日期的钟声正式编号。

在短期内,__proto__如果您的浏览器支持它(不是IE,也没有IE),那么您可以使用它。未来10年,它可能会在webkit和moz上运行,因为ES6在2013年才会最终完成。

Brendan Eich - re:ES5中新对象方法的方法

对不起,......但可设置的__proto__,除了对象初始化用例(即,在一个新的对象不可达,类似于ES5的Object.create),是一个可怕的想法。我写这篇文章的目的是__proto__在12年前设计和实施。 ...缺乏分层是一个问题(考虑使用关键字的JSON数据"__proto__")。更糟糕的是,可变性意味着实现必须检查循环原型链以避免il。。[需要对无限递归进行持续检查] 最后,__proto__对现有对象进行变异可能会破坏新原型对象中的非泛型方法,这对于__proto__正在设置的接收方(直接)对象来说不可能起作用。这通常是一种不好的做法,一种有意识的类型混淆。

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励