在js高级程序语言设计中关于作用域链和闭包那里我一直不理解。书上说,this是对象上下文,而闭包的作用域是包含了外部作用域(?),所以说是因为闭包作用域是全局所以闭包中的this就一定指向window?
在js高级程序语言设计中关于作用域链和闭包那里我一直不理解。书上说,this是对象上下文,而闭包的作用域是包含了外部作用域(?),所以说是因为闭包作用域是全局所以闭包中的this就一定指向window?
this就是一个普通的参数,当你使用a.b()调用函数b的时候,b里面的this就是a。你还可以使用call等函数强行指定this参数。所以不能说闭包就如何如何,这完全取决于拿到闭包的这个人怎么调用它,完全不取决于你怎么写。
至于指向window是浏览器自己的特殊规定,凡是没有指定this的,就是window。
因为js没有类,只有函数, 函数是可以谁都能来调用的,谁调用了函数,this就是谁, 也可以用A调用函数 然后apply/call(B,...) 直接把B当成this进去 js的this很无厘头 就好比打工的码农是干活的函数 ,今天在百毒打工,归李艳红指挥, 李艳红就是this, 明天码农又换一个腾讯公司打工,马花腾就是this, 还有一种码农是外派的,就好比码农本来是是华为的员工,派到阿里去干活了,码农.apply/call(阿里,...) 这样马云就成了this
1.对于声明的函数(不是对象的method)
node中的this,指向:系统级对象(或者可以理解为v8引擎)。
webworker中的this,指向:介于浏览器和window对象之间,js权威指南也是这么描述。
window中的this,指向:window,可以操作dom。对于这个this,严格模式下为undefined,非严格模式指向window。
自己创建的对象中的this,指向:自创建对象。
2.对于浏览器的window来说,记住两个规则。1.所有的函数只要不是自己创建对象的方法,this要么是undefined,要么就是window。2.所有的函数(方法)都可以通过bind,call,apply改变this指向(你可以很任性的干这件事)
js里面的this确实有点复杂,容易混淆。有兴趣可以参考下这篇文章,详细介绍了this的各种情况和原因https://segmentfault.com/a/1190000003906484。
this是执行上下文的一个属性,而不是某个变量对象的属性。当你在代码中使用this的时候,这个this的值是直接从执行上下文中获取的,所以this的值只取决于进入上下文时的情况。在全局上下文中,this的值就是指全局这个对象,在浏览器下就是window。在函数上下文中,this会根据每次的函数调用而有不同的值。this由每一次函数的调用者(caller)决定。这里又涉及到了js的内部类型-引用类型(Reference type)。这时候this可以分为三种情况:
1.调用括号左边是引用类型的值。此时this的值指向引用类型中的base对象。
2.调用括号左边是引用类型的值,但是该值为null。最终this指向全局对象。
3.调用括号左边不是引用类型的值。此时this结果为全局对象。
ps:要想彻底理解js中的this,建议可以去汤姆大叔的博客阅读下深入理解js系列。搞明白js的执行上下文,变量对象和什么是引用类型,这样才能理解不同情况下的this取值。
闭包里的this指向window,这是正确的。但是这并不是设计者故意为之,相反,这是一个设计缺陷,所以这其中并没有什么逻辑关系。
正是因为这样,闭包里不能使用this来引用函数所在的执行对象,所以我们通常在闭包函数内先将this赋值给that
,再在闭包内使用that就可以达到最初的目的。
记住,这是一个设计缺陷,没有什么逻辑。
8 回答4.8k 阅读✓ 已解决
6 回答3.5k 阅读✓ 已解决
5 回答2.9k 阅读✓ 已解决
5 回答6.4k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决
3 回答2.5k 阅读✓ 已解决
当你要确定“函数中的this是什么”的时候,永远不要到函数定义的地方去找答案!而是要到函数被调用的地方找答案!
具体说:函数里面的
this
的含义,是由它被调用的方式决定的。换句话说,当你看到下面的代码时:
你就可以确定f里面的
this
就是指a
,而不管f
是个什么玩意。当你看到下面的代码时:你就可以确定(不考虑
bind
,以及严格模式时情况下),f
里面的this
就是指全局对象window
。所以,函数定义的方式(通过函数声明、函数表达式、
new Function
)与this
的确定无关,有没有闭包也与this
无关!最后说一句:“this是由被调用的方式确定”这个事实,使得this可以被改变,从而为函数增加了动态性、可变性,使得编程更加灵活。
如果题主要从根本上理解关于this的方方面面,有时间请阅读ECMAScript规范:http://es5.github.io。
规范中关于函数调用表达式和函数执行过程的部分对此有完整和详细的说明。比如,关于this为什么会是window在这里:
10.4.3 Entering Function Code里面第二步。