看了“这个的方向看谁用了”这句话,就没有相关的问题能难倒我了。 打3也符合“这个方向看谁用”的观点 本来这个理论是无敌的,但是ES6有箭头功能,你可以破例,记住就好。 Output undefined,那是因为setTimeout传入的函数实际上是window使用的。 使用箭头功能,打印值变为2。 但需要注意的是,在严格模式下,使用独立函数时,这不会指向窗口。 自从看到“这个的方向看谁用了”这句话,就没有相关的问题能难倒我了。 不信,就这么简单。 例子:var a = 2;函数foo(){ console . log(this . a);} foo();//2这是独立函数调优最常见的用法。 谁用过?当然是window,window.foo 所以这个指向window,window.a自然是2 var a = 3;函数foo(){ console . log(this . a);}var obj = { a:2,foo:foo };obj . foo();//2打印输出2 谁用过foo函数?是obj 所以这指向obj This.a自然等于obj.a,obj . a等于2 但是这种情况有一点需要注意:var a = 3;函数foo(){ console . log(this . a);}var obj = { a:2,foo:foo };var func = obj.foofunc();//3什么,印了3,你还忽悠我!不用担心,func其实是对obj.foo的引用,引用的是foo函数本身,所以func()和foo()是一样的,所以这个指向window。 打3也符合“这个方向看谁用”的观点 函数foo(){ console . log(this . a);} var obj = { a:2 };foo . call(obj);//2call和apply会强制这个绑定到第一个参数,foo.call(obj)可以理解foo函数是obj用的,所以这个会指向obj。 var a = 2;function foo(){ this . a = 3;} var bar = new foo();a;//2;bar.a//3;这里的foo函数是new运算符使用的,它会自动执行以下步骤:1 .创建一个全新的对象;2.这个新对象将执行[[Prototype]]连接;3.这个新对象将被绑定到该函数所使用的;4.如果函数不返回其他对象,那么新表达式将自动返回这个新对象。所以当new调用foo时,这就指向了一个新的对象,bar。 因此,this.a修改了bar的属性。 本来这个理论是无敌的,但是ES6有箭头功能,你可以破例,记住就好。 它将根据外层作为使用范围来确定这一点。 function foo(){ setTimeout(function(){ console . log(this . a);})} var obj = { a:2 };foo . call(obj);//未定义的输出未定义。那是因为setTimeout传入的函数实际上是window使用的。 而a没有定义,所以type未定义。 但是有些人不理解,我就换种方式写吧。 函数fn(){ console . log(this . a);} setTimeout(fn);窗口用于调试,因此this.a未定义。 函数foo(){ setTimeout(()= > { console . log(this . a);})} var obj = { a:2 };foo . call(obj);//undefined使用箭头函数后,打印的值变成2。 其this属于foo()函数的操作域,foo被obj使用,所以会输出2。 现在这些问题都可以解释了。 但需要注意的是,在严格模式下,使用独立函数时,这不会指向窗口。 var a = 2;函数foo(){ " use strict " console . log(this . a);} foo()//未捕获的类型错误:无法读取属性:一个:的undefined OK,现在没什么能难倒你了。