关于apply第一个参数指定了函数体内this对象的指向,我之前的理解是:
A.apply(x,array);表明x调用函数A并传入参数数组array,即类似x.A(array[0],array[1]...),所以这样就很像方法调用模式很容易理解函数A内的this指向了x,即指定了函数体内this对象的指向。
这里有我第一个疑问:apply的第一个参数指定了函数体内this对象的指向就是这个意思吗?但这样理解挺麻烦的,好像不如直接无脑的想把第一个参数绑定到了函数的this上。
我的第二个疑问是最近看到了一段代码:
var getSingle=function(fn){
var ret;
return function(){
return ret || (ret=fn.apply(this,arguments));
}
};
var getScript=getSingle(function(){
return document.createElement("script");
});
var script1=getScript();
var script2=getScript();
alert(script1===script2);//true
var script3=window.document.createElement("script");
alert(script2===script3);//false???
这是我对这段代码的理解:
首先查了一下相关概念:每个函数在被调用时都会自动取得两个特殊变量:this和arguments。内部函数在搜索这两个变量时,只会搜索到其活动对象为止,因此在闭包中不可能直接访问到外部函数中的这两个变量。
执行var script1=getScript();相当于
var script1=getSingle(function(){
return document.createElement("script");
})();
此时属于函数调用模式,getSingle()函数内this指向了window,然后getSingle函数内的闭包
return function(){
return ret || (ret=fn.apply(this,arguments));
};
此时立即被调用,所以闭包中的
ret=fn.apply(this,arguments);也就是
ret=(function(){
return document.createElement("script");
}).apply(this,arguments)
这个apply里的this因为闭包立刻被调用执行所以也属于函数调用模式,进而也就指向了window。
然后这里就出现了我的第二个疑问,即
但如果按我之前的理解就类似于下面这种奇奇gaygay的东西
ret=~window.(function(arguments){
return document.createElement("script");
})=document.createElement("script");
所以我之前的理解只是适合方法调用模式。这里.apply(window,arguments)是不是直接可以不管了?就是默认绑定到全局环境了?
我自己加了最后两行代码,但是返回是false???然后我就懵了,是不是我对apply调用模式哪里理解错了?麻烦JS大神帮我解惑了[抱拳]
2018.5.22补充
首先这段代码是个简易的单例模式,即用一个变量来(ret)标志当前是否已经为某个类创建过对象,如果是,则在下一次获取该类的实例时(var script2=getScript();),
直接返回之前创建的对象(ret=document.createElement("script"))。
所以第一个alert中script1和script2就是同一个对象,所以返回true。但是我自己加的script3相当于新建了一个与1、2不同的引用类型的变量,所以肯定是false了。
你是对js的引用类型理解不充分
你运行一下上面的代码,看看结果
还有
相当于
或
ret=
window.(function(arguments){return document.createElement("script");
})=document.createElement("script");
是只有访问一个未定义的变量时,才会去window对象上面找