this关键字很难? 一层层给它剥开,发现它内心特别的纯洁
前言:在JavaScript中,this
是一个关键字,它的值取决于函数的调用方式。this
的作用是指向当前执行代码的对象,它在不同的情境下会有不同的值。所以this的指向是动态的。那我们要怎么判断this到底指向哪里呢?记住下面几条规则就够了。来来来,让我们一起来看看这个流氓this其实特别的守规则。
默认绑定规则
默认绑定规则:函数在哪个词法作用域中生效,this就指向哪里(独立调用的函数就是指向window)。
我们来举个简单的例子看一下
js
var a=1
function foo(){
console.log(this.a)
}
在全局声明了变量a=1,写了函数foo(),打印函数内部自带的关键字this,他会指向哪里呢?在浏览器的控制台运行,它是指向windows的,在这里我们要明白一个概念,this所在的函数在哪里生效,那么this指向这个地方的词法作用域,我们知道函数只有作用域没有词法作用域,所以指向windows这个全局词法作用域。
让我们在看一个例子 将上述的函数放在bar()函数中调用,那么this又会指向哪里呢?
js
var a=1
function foo(){
console.log(this)
}
function bar(){//bar的词法作用域是window
var a=2
foo()
}//foo是在bar的作用中调用,但是必须要知道bar的词法作用域中调用。
bar()
根据我们上面说的,this指向函数生效的那个词法作用域,那foo()函数是在bar()生效的,是不是指向bar()的词法作用域呢?看看结果到底指向哪
我们可以看到结果还是指向windows。理由很简单,像上文说的。this指向函数生效的词法作用域当中,this在bar()中被调用,自然是指向this的词法作用域那就是windows。
我们再来看一个例子
js
function foo(){
function bar(){
console.log(this)
}
bar()
}
foo()
按照上面的规则,你分析一下,一步步的来,bar()函数在foo()中生效是吧,那应该指向foo()的词法作用域是吧,那是不是得指向foo()
结果:
为什么还是指向windows?是不是上面说的出错了,并没有。还记得我们说的啥嘛。函数没有词法作用域,只有作用域,那么this是指向词法作用域的,foo()函数没有词法作用域,只能向上找,找到Windows这个全局词法作用域。看图理解一下。
总结就一句话,独立调用的函数this都指向windos,因为this指向词法作用域,而函数没有词法作用域,只能指向全局词法作用域windows.
隐式绑定规则
隐式绑定规则:当一个函数被对象拥有,且调用时,函数的this指向对象。 继续看个例子理解一下吧
js
function foo(){
console.log(this.a)
}
var obj = {
a:1,
foo:foo
}
obj.foo()
我们写了一个函数foo(),并写了一个对象,将foo()函数放在obj对象中,并用通过obj对象调用,诶,是不是区别于上面的独立调用。来看看结果吧。
结果是1,是不是符合我们的说法,此时this指向的就是obj对象。
所以,隐式绑定规则很简单就是一个函数被对象函数拥有并且被对象调用,那么this指向的就是这个对象。
隐式丢失
隐式丢失:当函数被多个对象链式调用时,this指向引用函数的那个对象。 举个栗子看一下吧,什么是隐式丢失
js
var obj = {
a:1,
foo:foo
}
var obj2={
a:2,
obj:obj
}
function foo(){
console.log(this.a)
}
obj2.obj.foo()
我们写了一个函数并被obj对象拥有,obj2对象又拥有obj对象,那通过obj2调用,this指向哪里呢?
显然结果是1,指向obj,就近原则,谁引用就指向谁。
显示绑定
显示绑定:call,apply,bind,用这些方法可以直接选择this的对象 举个栗子
js
function foo(){
console.log(this.a);
}
var obj ={
a:1
}
// foo.call(obj)
// foo.apply(obj)
let bar=foo.bind(obj)
bar()
看,通过这些方法也可以将this指向obj对象
new 绑定
this指向实例对象,这个我就不多赘述了,可以去查找一下new的使用规则,看看我以往的文章
箭头函数
函数是不是都有this这个关键字呢?不,箭头函数没有,所以箭头函数里面是没有this关键字的,它也就不能指向谁
总结
1.默认绑定规则:函数在哪个词法作用域中生效,this就指向哪里(独立调用的函数就是指向window)。
2.隐式绑定规则:当一个函数被对象拥有,且调用时,函数的this指向对象。
3.隐式丢失:当函数被多个对象链式调用时,this指向引用函数的那个对象。
4.显示绑定:call,apply,bind
5.new 绑定:this指向实例对象 到这this我们就分析的差不多了,是不是没有我们想象的那么难呢? 其实this是个挺纯洁的孩子呢,遵守这么多的规则。