网上看到一句话,匿名函数的执行是全局的,那怎么可能是全局的呢?this在闭包里面指向的是window,为什么指向window呢?下面通过js函数调用方式和一些情况来分析为什么this是这样,其实this的最终指向就是调用它的对象。这里的sayTwo相当于一个闭包。内部匿名函数的执行就是this的函数调用方式。具体情况2,通过调用方式分析varname='window'varperson={name:'Alan',sayOne:function(){console.log(this.name)},sayTwo:function(){returnfunction(){console.log(this.name)}}}人。sayOne()person.sayTwo()()结果第一个say是Alan打出来的,第二个是window原因函数里面的this指向调用者sayOne调用者是person对象,所以this指向此人;sayTwo的调用者虽然也是person对象,但不同的是这次调用没有类型this而是全局返回一个匿名函数。这个匿名函数不是作为一个对象的方法来调用和执行的,而是全局执行的。最后执行者是windowcase2匿名函数——函数调用方式分析varname='window'varperson={name:'one',wrap:function(){(function(){console.log(this.name)//窗口})()函数sum(){console.log(this.name)//window}sum()}}person.wrap()wrap里面是一个自执行的匿名函数,this.name打出来就是window。俗话说:this指向最后一个调用者;感觉没法分析,因为是自己执行,用函数调用的方式分析JS(ES5)。JS(ES5)中的三种函数调用形式:func(p1,p2)函数调用方式obj.child.method(p1,p2)方法调用方式func.call(context,p1,p2)上下文调用方式,可以看到方法不是通过对象调用的,而是直接执行的,属于函数调用方式。匿名函数的自动执行属于函数调用方式。我们定义的非匿名函数sum虽然是在对象中,但是并不是通过对象(obj.sum)直接调用的,而是在对象的函数中调用的,所以sum也属于函数调用方式。其实我们常见的调用方式是这样的:func(p1,p2)obj.child.method(p1,p2)其实都是语法糖,可以等价改成调用形式func.call(undefined,p1,p2)obj.child.method.call(obj.child,p1,p2);另外在浏览器中有一个规则:如果你传递的context是null或者undefined,那么window对象就是默认的context(严格模式context中默认是undefined)所以person.wrap()中匿名函数的thisabove指向window总体来说,呃,好像是这样的。所以嵌套的函数调用this很容易指向窗口,func.call(this)可以帮我解决。还有一些特殊情况需要从上层传入这个。我们使用letthat=this然后在func.call(that)中绑定this。通常指向window,然后返回一个匿名函数。2、返回的匿名函数绑定了事件,this指向被监听的元素(文档)3、fn实际上和上面返回的匿名函数形成了一个闭包,而fn其实就是一个匿名函数,匿名函数的执行是全球性的。fn内部的this应该指向window4。这里使用apply来修正this点,使fn内部的this指向文档=0;returnfunction(){//记录当前函数被触发的时间varnowTime=Date.now();if(nowTime-lastTime>delay){/*fn();console.log(this)//document*/fn.apply(this)//fixthis指向问题console.log(this)//document//同步时间lastTime=nowTime;}}}document.onscroll=throttle(function(){/*console.log(this)//窗口*/console.log(this)//documentconsole.log('scrolleventistriggered'+Date.now())},1000)参考JS高级编程案例,用call修改this指向varname="global";varfoo={name:"foo",getName:function(){console.log(this.name);}}varbar={name:"bar",getName:function(){return(function(){console.log(this.name);})();}}foo.getName();//foofoo.getName.call(bar);//barfoo.getName.call(this);//globalfoo.getName.call(窗口);//global(function(){console.log(this.name)}.bind(bar))();//bar(function(){console.log(this.name)}.bind())();//全球的
