__proto__,什么时候会消失?备择方案? [英] __proto__, when will it be gone? Alternatives?

查看:300
本文介绍了__proto__,什么时候会消失?备择方案?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Mozilla声称它会在一段时间后删除__proto__(~2008)并且它仍然在浏览器中。它仍然会被弃用吗?它适用于Opera,(我认为是Safari)和Chrome。我不需要担心IE,所以我很乐意继续使用它。

Mozilla claimed it would remove __proto__ a while back (~2008) and it is still in the browser. Is it still going to be deprecated? It works in Opera, (Safari I think) and Chrome as well. I don't need to worry about IE so I would love to keep using it.

但是,我不希望我的代码有一天停止工作,所以问我的问题:

However, I don't want my code to stop working one day, so on to my question:

__ proto__允许死亡简单继承:

__proto__ allows for dead simple inheritance:

a.__proto__ = {'a':'test'}

无论如何我能以符合标准的方式复制这个吗?我知道有功能继承,这很丑陋,而且它过于复杂,我只想创建一个原型链。只是想知道是否有任何巫师解决了这个问题。

Is there anyway I can replicate this in a standards compliant way? I know there is functional inheritance, that's ugly, and it over-complicates the fact that I just want to create a prototype chain. Just wondering if any wizards have solved this.

谢谢

推荐答案

注意:改变 <的价值被认为是一种不好的做法。 code> __原__ 。强烈建议不要使用JavaScript的创建者Brendan Eich。实际上 __ proto __ 属性已完全从Rhino等几个JavaScript引擎中删除。如果你想知道为什么然后阅读以下评论由Brendan Eich撰写。

Note: It's considered a bad practice to change the value of __proto__. Doing so is strongly discouraged by Brendan Eich, the creator of JavaScript, amongst others. In fact the __proto__ property has been removed entirely from a few JavaScript engines like Rhino. If you wish to know why then read the following comment by Brendan Eich.

更新:浏览器不会删除< a href =https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto\"rel =noreferrer> __ proto __ 财产。事实上, ECMAScript Harmony 现已标准化了 __ proto __ 属性和< a href =https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf\"rel =noreferrer> setPrototypeOf 功能。 __ proto __ 属性仅受遗留原因支持。强烈建议您使用 setPrototypeOf getPrototypeOf 而不是 __ proto __

Update: Browsers are not going to remove the __proto__ property. In fact, ECMAScript Harmony has now standardized both the __proto__ property and the setPrototypeOf function. The __proto__ property is only supported for legacy reasons. You are strongly advised to use setPrototypeOf and getPrototypeOf instead of __proto__.

警告:虽然 setPrototypeOf 现在是一个标准,你仍然不鼓励使用它,因为改变一个对象的原型总是会导致优化并使你的代码变慢。此外,使用 setPrototypeOf 通常表示代码质量差。

Warning: Although setPrototypeOf is now a standard, you are still discouraged from using it because mutating the prototype of an object invariably kills optimizations and makes your code slower. In addition, the use of setPrototypeOf is usually an indication of poor quality code.

你不喜欢不用担心你现有的代码有一天不工作。 __ proto __ 属性即将停留。

You don't need to worry about your existing code not working one day. The __proto__ property is here to stay.

现在,针对手头的问题。我们希望以符合标准的方式执行类似的操作:

Now, for the question at hand. We want to do something similar to this in a standards compliant way:

var a = {
    b: "ok"
};

a.__proto__ = {
    a: "test"
};

alert(a.a); // alerts test
alert(a.b); // alerts ok

显然你不能使用 Object.create 实现这一目标,因为我们没有创建新对象。我们只是想改变给定对象的内部 [[proto]] 属性。问题是,一旦创建对象,就无法更改对象的内部 [[proto]] 属性(除非使用 __ proto __

Obviously you can't use Object.create to achieve this end since we are not creating a new object. We are just trying to change the internal [[proto]] property of the given object. The problem is that it's not possible to change the internal [[proto]] property of an object once it's created (except via using __proto__ which we are trying to avoid).

所以为了解决这个问题,我写了一个简单的函数(注意它适用于除函数之外的所有对象):

So to solve this problem I wrote a simple function (note that it works for all objects except for functions):

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;
}

因此我们现在可以在创建后更改任何对象的原型,如下所示(请注意,我们实际上并没有更改对象的内部 [[proto]] 属性,而是创建一个具有与给定对象相同属性的新对象,并继承自给定原型):

So we can now change the prototype of any object after it's created as follows (note that we are not actually changing the internal [[proto]] property of the object but instead creating a new object with the same properties as the given object and which inherits from the given prototype):

var a = {
    b: "ok"
};

a = setPrototypeOf(a, {
    a: "test"
});

alert(a.a); // alerts test
alert(a.b); // alerts ok

<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>

简单高效(我们没有使用 __ proto __ 属性)。

Simple and efficient (and we didn't use the __proto__ property).

这篇关于__proto__,什么时候会消失?备择方案?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆