1.this的使用场景
我们先把this
的使用场景分为两大类:函数外和函数内:
函数外的this
就是在全局代码里,直接使用this:
"use strict";
let name = "window";
console.log(this);
console.log(this.name);
// Window
// 'window'
从结果看,在函数外的this指向很简单,就直接指向的是全局变量Window
对象,(浏览器环境,以下代码都是在浏览器环境)
而且严格模式或非严格模式都是。
函数内部的this
而在函数内部使用的时候,就可以分为以下几类:
- 函数独立调用
- 函数作为对象的方法被调用
- 函数作为构造函数调用
- 函数通过call,apply,bind调用
this指向确定的时间
在分析不同情况this
的指向之前,我们确认一个很重要的问题,就是this的指向是什么时间确定的。
在说这个问题之前,需要简单说一下执行上下文
,如果有看过: js的闭包、执行上下文、作用域链 这篇文章,我们就会知道执行上下文
包含三个部分:
- 变量对象
- 作用域链
- this指向
我们发现this
其实执行上下文
的一部分,当代码需要用到this的时候,也是从这里取的。所以执行上下文
创建的时间,就是this确定的时间。
而执行上下文
的创建时间是:函数被调用,但是还没执行具体代码之前。
所以this
的指向确定的时间也就明确了:当函数被调用的时候,才开始确定this指向。
2.分场景分析this指向
在了解了this
被确定的时间后,我们现在来按上面所列出的场景,来具体分析在函数里面的this
:
2.1 函数独立调用时
函数对立调用,其实就是我们最常见的以函数名直接调用函数:
// code-01-非严格模式
var name = "window";
function fun() {
var name = "function";
console.log(this);
console.log(this.name);
}
fun()
// >> Window
// >> 'window'
我们看到,当这样调用函数时,this
指向的是全局对象Window
,所以this.name
就相当于Window.name
:‘window’,而不是函数的内部变量name=‘function’
这里有一点需要说明的是,这是在非严格模式
下,那如果是在严格模式
下呢?我们看下面的例子:
// code-01-严格模式
"use strict"
var name = "window";
function fun() {
var name = "function";
console.log(this);
console.log(this.name);
}
fun()
// >> undefined
// >> 报错
从结果来看,在严格模式
下,独立调用函数时,函数内部的this指向是 undefined
其实应该这么说:不管是严格模式还是非严格模式,独立调用函数时,函数内部的this指向都是 undefined
,只不过在非严格模式下,js会自动把undefined的this默认指向全局对象:Window
2.2 函数作为对象的方法调用
函数作为一个对象的方法调用,我们举例来看: