前言
this是什么?this指向谁?很多人包括我自己在刚接触到JavaScript中的this关键字时都会有这样两个问题。在经历了一系列的学习之后,我对this也有了一些自己的理解,当然作为初学者,我也并不能十分全面的解析this到底是什么,具体用法有什么,本文我会谈谈我对this的理解,希望对初学者有一定的帮助。
this的定义
什么是this? this是JavaScript保留的的一个关键字,用来引用它所属的对象。当一个函数调用时,会创建一个执行上下文,这个执行上下文包含函数在哪里调用(调用栈),函数的调用方法,传入的参数,this就是用来记录当这个执行上下文信息的一个属性。
this的指向
this的指向取决于this使用的位置
- 单独使用时,this指向全局
- 在函数中使用,this指向函数调用时,调用栈的位置
- 在构造函数中,this指向实例对象
- 在定时器,立即执行函数中,this指向全局
- 使用call(),apply()方法时,this指向函数所指的对象
- 闭包中this默认指向全局
this的绑定规则
1.默认绑定
在不调用其他绑定规则时,就是使用默认绑定,一般是独立函数的调用
function foo(){
console.log(this.a);
}
var a = 2
foo() // 2
2.隐式绑定
函数的调用通过了某个对象,this就指向这个对象
let obj = {
name: 'obj',
foo: function () {
console.log(this.name); //this指向obj
}
}
obj.foo()
上面这段代码中,将foo的值设置为一个函数,并使用obj这个对象去调用foo。因此,foo中的this指向obj 打印的结果将会是 “obj"
值得我们注意的是在隐式绑定中,在对象的属性链中,只有最后一层会影响调用的位置,也就是this的指向。如下面的代码:
function foo() {
console.log(this); // obj5
}
var obj4 = {
foo: foo,
obj5: {
a:1,
foo: foo
}
}
obj4.obj5.foo();
最后的结果为:obj5
隐式绑定还会出现隐式丢失的现象。
//隐式丢失
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
foo: foo
}
var bar = obj.foo
var a = 'glob'
bar() //glob 隐式绑定丢失 走默认绑定
上面的代码中,obj.foo引用了foo,而bar通过obj也引用了foo,可以发现,这段代码没有obj也能实现一样的效果,最后bar拿到全局下调用,this指向全局。
隐式丢失还有一种情况就是函数作为参数(回调函数)
function foo(fn){
var a = 2
fn()
}
function bar(){
console.log(this.a); // 4
}
let obj = {
a: 3,
bar: bar
}
var a = 4
foo(obj.bar)
3.显示绑定
显示绑定就是通过call,apply,bind的方式,call,apply和bind的第一个参数,就是对应函数的this所指向的对象。call和apply都会执行对应的函数,而bind方法不会。
//显式绑定
function foo() {
console.log(this.a);
}
var obj = {
a: 2,
}
foo.call(obj) // 2
new绑定
使用new方法this指向实例化之后的对象
new在干的事情
- 创建一个新的对象,并把构造函数中的this指向这个空对象
- 对这个对象执行[[原型]]连接
- 构造函数的方法,属性被添加到this引用的对象之中
- 如果构造函数中没有返回其它对象,返回出来这个对象
箭头函数
箭头函数没有自己的this指向箭头函数的this指向他的父级的this