JavaScript之this关键字

158 阅读4分钟
原文链接: mp.weixin.qq.com
  • what?why?

  • this四大绑定规则

  • this绑定指向的改变-apply/call/bind

  • this绑定注意点

  • 总结

 

一、what?why?

在Javascript中,当一个函数被调用时,会创建一个活动记录(也称为执行上下文)。它包含函数在哪里调用、函数的调用方式、传入的参数等信息。this就是这个记录的一个属性,会在函数 执行的过程中用到。this关键字是在运行时进行绑定的,与函数声明的位置没有任何关系,它指向什么完全取决于函数在哪里被调用

this关键字提供 了更优雅的方式来隐式“传递”一个对象引用。因此,可以将API设计的更加简洁易用。

 

二、this四大绑定规则

1.函数绑定(默认绑定) 

当直接调用函数时就是函数绑定模式。

注意:在非严格模式下,this将绑定到全局对象window。然而,在严格模式下,this 将绑定到undefined。 

 

2.隐式绑定(方法调用)

当函数作为一个对象的属性被调用的时候就属于隐式绑定模式,此时,this指向是调用这个函数的对象。

注意:被隐式绑定的函数会丢失绑定对象,此时,将会应用默认绑定,从而把this绑定到全局对象或undefined上。 

我们来看下面的这个例子。

虽然bar是obj.foo的一个引用,但是实际上它引用的是foo函数本身,因此此时的bar()其实是不带任何修饰的函数调用,因此应用了默认绑定方式。

参数传递也是一种隐式赋值,对于上面的这个例子,实际上执行了以下两个步骤:

            ①   fun=obj.foo

            ②   fun()

 

3.显式绑定(硬绑定)

在Javascript中,通常使用call/apply/bind方法来进行显示绑定。

在上面的这个例子中,创建了函数bar(),函数内部强制把foo函数中的this绑定到了对象obj 上。此后,无论如何调用函数bar,总会将obj绑定到foo中的this上。

 

4.new绑定(构造器绑定) 

通过new关键字调用的函数,属于new绑定模式。这时this关键字指向这个新创建的对象。

this关键字绑定规则的判定顺序

1. 函数是否是new绑定?如果是,则this指向新创建的对象;

2. 函数是否通过call/apply/bind显式绑定或硬绑定?如果是,则this指向指定的对象;

3. 函数是否在某个上下文对象中隐式调用?如果是,this绑定的是那个上下文对象;

4. 上述全不是,则使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到全局window对象。

Javascript this决策树(非严格模式下)

 

 

 

三、 this绑定指向的改变-call/apply/bind

3.1 call/apply/bind函数的用法

apply:

function.apply(obj,args)

obj:将代替function类里this对象

args:数组,它将作为参数传给function

立即执行

 

call:

function.call(obj,[param1[,param2[,…[,paramN]]]])

obj:将代替function类里的this对象

parms:这是一个参数列表

立即执行

bind:

function.bind(obj,arg1,arg2,...)

不会立即执行,而是返回一个新的函数。

Person.apply(this,arguments)

this:在创建对象的时候代表的是student

arguments:数组,即[“qian”,”21”,”一年级”] ,用Student去执行Person这个类里面的内容,如果在Person这个类里面存在this.name等之类的语句,这样就将属性创建到了student 对象里面。 

 

3.2 被忽略的this

3.2.1 忽略this

如果将null或者undefined作为this的绑定对象传入call、apply 或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。

非常常见的做法是使用apply来“展开”一个数组,并当作参数传入一个函数如:求数组最大最小值,合并数组等,具体用法如下:

var min = Math.min.apply(null, arr);

var max = Math.max.apply(null, arr);

Array.prototype.push.apply(arrA, arrB);

 

3.2.2.ES6箭头函数 

箭头函数不使用this的四种绑定规则,而是根据外层(函数或者全局)作用域来决定this的指向。请看下面的几个例子。

 

箭头函数中的this只和定义它的作用域的this有关,而与在哪里以及如何调用它无关,同时它的this指向是不可以改变的。

 

四、总结

本文主要介绍了this的四大绑定规则、this关键字指向的改变,以及this绑定的注意点(忽略this以及ES6中的箭头函数)。如果大家对this关键字还是没有弄明白,想继续深入理解this的其他用法,推荐下面的这本书。


欢迎关注《前端事儿》。有一天,你会感谢现在的自己。