JavaScript中Apply调用模式的this指向

关于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了。


人到中年有点甜
浏览 559回答 2
2回答

慕盖茨4494581

你是对js的引用类型理解不充分console.log(document.createElement("script")===document.createElement("script"))你运行一下上面的代码,看看结果还有ret=fn.apply(this,arguments)相当于ret=document.createElement("script");或ret=(function(){    return document.createElement("script");}).apply(this,arguments)ret=window.(function(arguments){return document.createElement("script");})=document.createElement("script");是只有访问一个未定义的变量时,才会去window对象上面找

慕桂英3389331

A.apply(x,array)等价于(A.bind(x))(...array)多看吧,也许以后能懂,我心里明白但是讲不明白就是你这个fn.apply(this,arguments)并不等于window.fn.apply(this.arguments)因为这个fn有定义
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript