5

win指向window. NS是这篇文章的临时命名空间。我想如果我想访问setTimeout,我可以像这样复制函数引用:

NS.setTimeout = win.setTimeout;

但是,执行会抛出错误:

NS_ERROR_XPC_BAD_OP_ON_WN_PROTO: Illegal operation on WrappedNative prototype object @ ...

为了解决这个错误,我刚刚做了:

NS.setTimeout = function (arg1, arg2) {
    return win.setTimeout(arg1, arg2);
};

但是,我不知道为什么这解决了它。我不知道是什么语言机制导致了这种行为。

4

3 回答 3

8

你想要的是这个:

NS.setTimeout = win.setTimeout.bind(win);

或者你已经做了什么,如果你想与 IE8 兼容。

因为setTimeout和许多window函数一样,需要接收器 ( this) 是window

另一个 IE8 兼容的解决方案,在我看来比你的更优雅(因为它不使用你知道所需参数数量的事实setTimeout),将是

NS.setTimeout = function(){
  return win.setTimeout.apply(win, arguments);
};
于 2013-07-25T13:46:17.070 回答
4

您不能这样做的原因是,在分配时,您正在更改 的调用上下文setTimeout,这是不允许的。
也不允许setInterval, 和许多其他本机对象/函数。再说一遍:一个很好的经验法则:如果您不拥有该对象,请不要触摸它。由于函数是 JS 中的对象,因此该规则也适用于它们

检查全局对象及其属性/内置函数的规范:

每当 ECMAScript 程序开始执行时,都会有某些内置对象可用。一,全局对象,是执行程序的词法环境的一部分。其他的可作为全局对象的初始属性访问。

等等。但是词汇环境非常重要。通过在别处分配对函数的引用,您很可能会掩盖部分词汇环境,或者暴露太多的全局环境(例如混搭)。

于 2013-07-25T13:47:26.593 回答
0

这解决了问题,因为您在调用时将调用对象更改回原始对象。

return win.setTimeout(arg1, arg2);

将上下文(或 this )设置回它应该在的窗口。其他答案的相似之处在于它们使用bindto将上下文更改为正确的值apply

于 2013-07-26T15:20:24.470 回答