jdw*_*jdw 16 javascript prototype-programming
Mozilla声称它会在一段时间后删除__proto__(〜2008)并且它仍然在浏览器中.它仍然会被弃用吗?它适用于Opera,(我认为是Safari)和Chrome.我不需要担心IE,所以我很乐意继续使用它.
但是,我不希望我的代码有一天停止工作,所以问我的问题:
__proto__允许死简单继承:
a.__proto__ = {'a':'test'}
Run Code Online (Sandbox Code Playgroud)
无论如何,我能以符合标准的方式复制这个吗?我知道有功能继承,这很丑陋,而且它过于复杂,我只想创建一个原型链.只是想知道是否有任何巫师解决了这个问题.
谢谢
Aad*_*hah 25
注意:改变它的值被认为是一种不好的做法__proto__.强烈建议不要使用JavaScript的创建者Brendan Eich.事实上,该__proto__属性已完全从像Rhino这样的JavaScript引擎中删除.如果你想知道为什么然后阅读Brendan Eich 的以下评论.
更新:浏览器不会删除该__proto__属性.实际上,ECMAScript Harmony现在已经标准化了__proto__属性和setPrototypeOf功能.该__proto__物业仅受遗留原因支持.强烈建议您使用setPrototypeOf而getPrototypeOf不是__proto__.
警告:虽然setPrototypeOf现在是标准,但仍然不鼓励使用它,因为改变对象的原型总是会导致优化并使代码变慢.此外,使用setPrototypeOf通常表示代码质量差.
您无需担心现有代码有一天无法运行.该__proto__物业将留在这里.
现在,针对手头的问题.我们希望以符合标准的方式执行类似的操作:
var a = {
b: "ok"
};
a.__proto__ = {
a: "test"
};
alert(a.a); // alerts test
alert(a.b); // alerts ok
Run Code Online (Sandbox Code Playgroud)
显然,Object.create由于我们没有创建新对象,因此无法实现此目的.我们只是试图改变[[proto]]给定对象的内部属性.问题是,[[proto]]一旦创建对象,就无法更改对象的内部属性(除非通过使用__proto__我们试图避免的对象).
所以为了解决这个问题,我编写了一个简单的函数(注意它适用于除函数之外的所有对象):
function setPrototypeOf(obj, proto) {
var result = Object.create(proto);
var names = Object.getOwnPropertyNames(obj);
var getProp = Object.getOwnPropertyDescriptor;
var setProp = Object.defineProperty;
var length = names.length;
var index = 0;
while (index < length) {
var name = names[index++];
setProp(result, name, getProp(obj, name));
}
return result;
}
Run Code Online (Sandbox Code Playgroud)
所以我们现在可以在创建它之后更改任何对象的原型(请注意,我们实际上并没有更改[[proto]]对象的内部属性,而是创建一个与给定对象具有相同属性并且从给定原型继承的新对象):
var a = {
b: "ok"
};
a = setPrototypeOf(a, {
a: "test"
});
alert(a.a); // alerts test
alert(a.b); // alerts okRun Code Online (Sandbox Code Playgroud)
<script>
function setPrototypeOf(obj, proto) {
var result = Object.create(proto);
var names = Object.getOwnPropertyNames(obj);
var getProp = Object.getOwnPropertyDescriptor;
var setProp = Object.defineProperty;
var length = names.length;
var index = 0;
while (index < length) {
var name = names[index++];
setProp(result, name, getProp(obj, name));
}
return result;
}
</script>Run Code Online (Sandbox Code Playgroud)
简单而有效(我们没有使用该__proto__属性).
我认为Mozilla想要提出的实际观点是它是非标准的,因此实现者完全可以将其删除.
更简洁的做原型链的方法是Object.create.a使用原型创建对象的等效代码{'a': 'test'}是:
a = Object.create({'a':'test'})
Run Code Online (Sandbox Code Playgroud)
如果您需要使用一个垫片,也可以在不支持它的浏览器中模仿此功能,这是直接搞乱的另一个优点__proto__.
| 归档时间: |
|
| 查看次数: |
6118 次 |
| 最近记录: |