繁体   English   中英

如何返回内置函数作为对象属性?

[英]How can I return a built-in function as a object property?

在某些情况下,此代码有效。 如果返回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!');

但是,当它返回警报(或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设置为警报时,如何使其正常运行?

问题在于,在某些实现中,警报实际上是窗口对象的正确方法。 也就是说,alert希望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)};
            }
        }
    })();        
}

为什么不返回一个匿名函数,该匿名函数又返回内置函数?

就像是

return function(msg) { alert(msg); }

我怀疑您遇到的问题不是由于您的设置方式,而是由于所涉及的功能。 console.log在上下文( this值)设置为console的情况下调用log函数。 如果你这样做

var f = console.log;
f("Hi there");

...请注意, log是在不同的上下文中调用的(在本例中是全局对象,在浏览器中是window ), this不再是console对象。

如果您这样做:

var obj = {};
obj.f = console.log;
obj.f();

...然后将以obj this形式调用log

某些功能会在意,因为某些功能在其实现中使用了this功能。 某些功能不会在乎,因为它们不在乎。 可能是alert并不在乎,因为它恰好发生在它期望thiswindow ,而这恰恰就是调用函数raw时的情况(例如,不通过点分符号或其他显式设置的方式) this ),因为(再次) window是在浏览器中的全局对象。

作为单独的注释:在大多数实现中,您看到的内置函数是正确的JavaScript函数对象,并且具有所有功能。 尽管在某些实现中(Internet Explorer是其中之一),它们根本不是适当的JavaScript函数,并且缺少适当函数的某些功能,例如applycall属性。 如有疑问,请包好。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM