在某些情况下,此代码有效。如果它返回console.log
,那么对p.out
的调用就可以了。
function Notice(mode) {
this.debug = mode;
this.out = (function() {
if(mode) {
if(window.console) {
return console.log;
} else {
return alert;
}
} else {
return Notice.doNothing;
}
})(mode);
}
var p = new Notice('1');
p.out('Kool-aid, OH YEAH!');
然而,当它返回alert(或window.alert)时,我收到一个错误:
Error: uncaught exception: [Exception... "Illegal operation on WrappedNative prototype object" nsresult: "0x8057000c (NS_ERROR_XPC_BAD_OP_ON_WN_PROTO)" location: "JS frame :: http:// .. :: <TOP_LEVEL> :: line 22" data: no]
作为一个简单的测试,这可行:
out = (function() { return alert; })();
out('hello dolly');
如果obj.out被设置为警报,我该如何才能正常运行?
答案 0 :(得分:5)
问题在于,在某些实现中,警报实际上是窗口对象的正确方法。也就是说,警报期望this
成为窗口对象。这以最简单的形式说明了问题:
var foo = {alert : alert};
/* this fails because the value of 'this' is foo:
*/
foo.alert('hello');
/* but this works because we re-point 'this to the
* correct object, that is the window object:
*/
foo.alert.call(window,'hello');
因此,解决您的问题的方法是返回一个直接调用alert的函数或绑定窗口以在闭包中发出警报。这样的事情:
function Notice (mode) {
this.out = function(message) {
if(mode) {
if(window.console) {
console.log(message);
} else {
alert(message);
}
}
};
}
或者这个:
function Notice (mode) {
this.out = (function() {
if(mode) {
if(window.console) {
return console.log;
} else {
return function (message) {alert(message)};
}
}
})();
}
答案 1 :(得分:3)
为什么不返回一个匿名函数,该函数反过来调用内置函数?
像
这样的东西return function(msg) { alert(msg); }
答案 2 :(得分:1)
我怀疑你遇到的问题不是因为你如何设置它,而是因为涉及的功能。 console.log
调用log
函数,并将上下文(this
值)设置为console
。如果你这样做
var f = console.log;
f("Hi there");
...请注意log
使用不同的上下文调用(在本例中为全局对象,在浏览器中为window
),{{1} }不再是this
对象。
如果你这样做:
console
...然后var obj = {};
obj.f = console.log;
obj.f();
将log
调用为obj
。
有些函数会关心,因为有些函数在实现中使用this
。有些功能不关心,因为它们没有。可能是this
并不关心,因为恰好它会使alert
成为this
- 这正是你调用函数raw时的情况(例如,不是通过点分表示法或以其他方式明确设置window
),因为(再次)this
是浏览器中的全局对象。
作为一个单独的注释:在大多数实现中,您看到的内置函数是适当的JavaScript函数对象并具有其所有功能。在某些实现中,虽然(Internet Explorer是一个),但它们根本不是合适的JavaScript函数,它们缺少适当函数的某些功能,例如window
和apply
属性。如果有疑问,请换行。