为了账号安全,请及时绑定邮箱和手机立即绑定

JavaScript中Apply调用模式的this指向

JavaScript中Apply调用模式的this指向

人到中年有点甜 2019-03-19 17:19:33
关于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);//truevar 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了。
查看完整描述

2 回答

?
慕盖茨4494581

TA贡献1850条经验 获得超11个赞

你是对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对象上面找


查看完整回答
反对 回复 2019-04-03
?
慕桂英3389331

TA贡献2036条经验 获得超8个赞

A.apply(x,array)
等价于
(A.bind(x))(...array)
多看吧,也许以后能懂,我心里明白但是讲不明白


就是你这个
fn.apply(this,arguments)
并不等于
window.fn.apply(this.arguments)
因为这个fn有定义

查看完整回答
反对 回复 2019-04-03
  • 2 回答
  • 0 关注
  • 557 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号