在IE9和IE10中绕过__proto__的限制
在IE9和IE10中绕过__proto__的限制
大家好,Javascript 忍者们!我有一个非常棘手的问题需要解决,但是找不到令人满意的解决方案。\n对于我正在开发的一个非常特定的Javascript框架,我需要能够设置动态创建函数的__proto__属性。我有一种通用的函数工厂,需要为创建的函数设置共同的定义。\n我不想争论这是否是一个好的实践,因为我真的需要出于完全合理的原因来实现这一点。\n以下是一个在最新版本的Chrome上完美运行的小型QUnit示例,展示了我所需要的内容:\n
var oCommonFunctionProto = {}; var fnCreateFunction = function () { var fnResult = function () {}; fnResult.__proto__ = oCommonFunctionProto; // 在IE9或IE10中无法工作 return fnResult; }; var fn1 = fnCreateFunction(); oCommonFunctionProto.randomMethod = function() { return 10; }; equal(fn1.randomMethod(), 10, "__proto__已经正确设置"); var oInstance = new fn1(); // fn1可以实例化
\n正如您在这段代码中所看到的,添加到oCommonFunctionProto的任何内容都将直接在fnCreateFunction方法返回的任何函数上可用。这允许在Function对象上构建原型链(就像经常在对象的原型链上做的那样)。\n问题在于:在IE9和IE10中,__proto__属性是不可变的,不幸的是,我确实需要与这些浏览器兼容。\n此外:\n
- \n
- 我不能使用任何第三方。我需要一个完全功能的代码,不依赖于其他任何东西。
- 正如您所看到的,randomMethod是在函数创建之后添加的。在我的场景中,我确实需要原型链,因为这些对象在函数创建之后将被修改。简单地在函数原型上复制oCommonFunctionProto的属性将不起作用。
- 只要能完成工作,我对次优化的代码完全可以接受。这将是一个兼容性的hack,只针对IE9/IE10。只要能完成工作,我就满意。
- 在函数创建时设置__proto__可能是可以接受的。如果没有选择,这样做更好,但如果没有选择,这是可以接受的。
\n
\n
\n
\n
\n我尝试了所有可能的方法,但是没有找到任何办法来绕过IE9/IE10上的这个限制。\nTL;DR:我必须能够在IE9和IE10中设置Javascript函数的__proto__,而不需要任何第三方的帮助。
在IE9和IE10中,无法绕过__proto__限制。根据其他答案和讨论,似乎在IE<11中这是不可能的。
最后,我放弃了对象或函数的原型链,转而使用了扁平化的原型,并在逻辑上“父级”原型发生变化时通知“子级”原型进行更新。
以下是解决这个问题的代码示例:
function updateChildPrototype(child, parent) { child.__proto__ = parent; } function Parent() { this.name = 'Parent'; } function Child() { this.age = 10; } var parent = new Parent(); var child = new Child(); console.log(child.name); // undefined updateChildPrototype(child, parent); console.log(child.name); // Parent
通过调用updateChildPrototype函数,我们可以将child对象的原型设置为parent对象,从而解决了在IE9和IE10中无法绕过__proto__限制的问题。