作为原型的窗口使得setTimeout表现得很奇怪

时间:2016-05-05 13:14:19

标签: javascript

这个问题与我之前的问题(using window as a prototype returns seemingly wrong values in javascript)有关,@ Stubb0rn回答了这个问题,但我遇到了另一个问题:

function W(){
    var w=this;
    Object.defineProperty(this,'window',{configurable:true,enumerable:true,writable:false,value:w});
}
W.prototype=window;
window.setTimeout(function(){console.log("123")});     // works ok
(new W()).setTimeout(function(){console.log("123")});  // throws Uncaught TypeError: Illegal invocation(…)

请注意我使用chrome来测试

1 个答案:

答案 0 :(得分:0)

解决了它,它需要从窗口上下文中调用本机函数,所以我结束了窗口中的函数绑定并进行双原型化,如下所示:

function define(w){ // for testing I use requirejs define instead
    window.Test123=w;
}
(function(){
    function WBase(){
        for(var i in window){
            if(typeof window[i]=='function'){
                this[i]=window[i].bind(window);
            }
        }
    }
    WBase.prototype=window;
    function W(){
        var w=this;
        Object.defineProperty(this,'window',{configurable:true,enumerable:true,writable:false,value:w});
    }
    W.prototype=new WBase();
    define(function(){
        var windowAlias=new W();
        return (function(window){
            var ret={}; // returns only the variables added to the alias window object
            with(window){

                // CODE FROM MODULE HERE WILL HAVE an alias to "window" wich means if it adds variables to window (global scope) it will be prevented and instead added to the alias window

                for(var i in window){
                    if(window.hasOwnProperty(i)&&i!='window')
                        ret[i]=window[i];
                }
            }
            return ret;
        }).call(windowAlias,windowAlias)
    });
})();

Test123();  // for testing

尝试粘贴jquery代替注释(// CODE FROM MODULE HERE ...),您将获得一个具有属性jQuery和$的对象,并且它们不会被添加到全局范围。我最终创建了一个页面,动态地为通过查询字符串

请求的javascript文件追加这些行