在执行上下文的创建阶段,会分别生成变量对象,建立作用域链,确定this指向。其中变量对象总结过了,今天就是要确定this的指向。
本文最最核心的一句话就是:this是在函数调用的时候确定的,一定要牢牢记住,其次,在函数执行过程中,this
一旦被确定,就不可更改了。
1 | var a = 10; |
this是什么
重点:this是一个对象,是对象和函数之间达成关联关系的纽带,是在函数调用的时候确定。
怎么确定this的指向
因为this是在函数调用的时候确定的,所以this的指向是很灵活的,所以很多人对this的指向总是似懂非懂。那么这里可以告诉大家一个套路,也是本文唯一的套路,按照这个套路走,以后this的问题再也难不倒你了。
当你不能确定this
指向哪里的时候,尝试把函数的调用转换为 call/apply
的形式,call/apply
的第一个参数就是this的指向!
call/apply手动指定this
call/apply
可以自行手动设置this的指向。所有的函数都具有着两个方法,它们除了参数略有不同,其功能完全一样。它们的第一个参数都为this
将要指向的对象。call/apply
的具体使用这里就不讲了,如果不熟悉call/apply的用法 送你传送门
1 | function fn(param) { |
- call/apply第一个参数如果传入的是简单数据类型,会被自动包装为对象
1 | function f(){ |
call/apply第一个参数如果没传,或者传入的是null/undefined的时候,this的指向跟是否在严格模式下有关。
非严格模式下,this指向全局对象(浏览器是window)。
1
2
3
4
5
6function f(){
console.log(this)
}
f.call(); // Window {postMessage: ƒ,...}
f.call(null); // Window {postMessage: ƒ,...}
f.call(undefined); // Window {postMessage: ƒ,...}严格模式下,this指向null/undefined
1
2
3
4
5
6
7
8
function f(){
console.log(this)
}
f.call(); // undefined
f.call(null); // null
f.call(undefined); // undefined
几个栗子
只要掌握call/apply
,结合是否严格模式,你就会发现虚无缥缈的this
已经有迹可循了,下面例子中的函数调用代码都可以通过转换的call
模式代码直接替换。
- 纯粹的函数调用
1 | // 非严格模式 |
- 作为对象方法的调用
1 | function test() { |
- 作为构造函数调用,
this
就指向构造出来的新对象
1 | function Test() { |
- 通过call/apply改变this指向,将类数组对象转换为数组,
1 | function exam(a, b, c, d, e) { |
- 根据自己的需要灵活修改this指向
1 | var foo = { |
总结
我们可以将平时通过括号、通过.
、通过new
去使用函数的方式,看做是call/apply
的语法糖,是简写版,想要深入理解函数的调用,就要学好call
。
关于this
的部分已经总结完了,希望这篇文章有助于你准确的理解this
关键字,能够真正学到东西。
参考
this 的值到底是什么?一次说清楚
你怎么还没搞懂 this?
JS 的 new 到底是干什么的?
Javascript 的 this 用法
全方位解读this