多语言展示
当前在线:1167今日阅读:97今日分享:45

JS中的this、apply、call、bind

在 ES5 中,其实 this 的指向,始终坚持一个原理:this 永远指向最后调用它的那个对象,来,跟着我朗读三遍:this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象,this 永远指向最后调用它的那个对象。
工具/原料

JavaScript

方法/步骤
1

来看一个最简单的例子:例 1:

2

自定义参数log 的是 windowsName,因为根据刚刚的那句话“this 永远指向最后调用它的那个对象”,最后调用 a 的地方 a();,前面没有调用的对象那么就是全局对象 window,相当于是 window.a();注意,这里没有使用严格模式,如果使用严格模式的话,全局对象就是 undefined,那么就会报错 Uncaught TypeError: Cannot read property 'name' of undefined。再看下这个例子:例 2:

3

在这个例子中,函数 fn 是对象 a 调用的,所以打印的值就是 a 中的 name 的值。做一个小小的改动:例 3:

4

这里打印 Cherry 的原因也是因为刚刚那句话“this 永远指向最后调用它的那个对象”,最后调用它的对象仍然是对象 a。再来看一下这个例子:例 4:

5

调用 fn 的是 a 对象,也就是说 fn 的内部的 this 是对象 a,而对象 a 中并没有对 name 进行定义,所以 log 的 this.name 的值是 undefined。这个例子还是说明了:this 永远指向最后调用它的那个对象,因为最后调用 fn 的对象是 a,所以就算 a 中没有 name 这个属性,也不会继续向上一个对象寻找 this.name,而是直接输出 undefined。再来看一个比较坑的例子:例 5:

6

为什么不是 Cherry,这是因为虽然将 a 对象的 fn 方法赋值给变量 f 了,没有调用,再接着跟我念这一句话:“this 永远指向最后调用它的那个对象”,由于刚刚的 f 并没有调用,所以 fn() 最后仍然是被 window 调用的。所以 this 指向的也就是 window。由以上五个例子可以看出,this 的指向并不是在创建的时候就可以确定的,在 es5 中,永远是this 永远指向最后调用它的那个对象。再来看一个例子:例 6:

7

怎么改变 this 的指向改变 this 的指向我总结有以下几种方法:使用 ES6 的箭头函数在函数内部使用 _this = this使用 apply、call、bindnew 实例化一个对象例 7:

8

在不使用箭头函数的情况下,是会报错的,因为最后调用 setTimeout 的对象是 window,但是在 window 中并没有 func1 函数。在改变 this 指向这一节将把这个例子作为 demo 进行改造。箭头函数ES6 的箭头函数是可以避免 ES5 中使用 this 的坑的。箭头函数的 this 始终指向函数定义时的 this,而非执行时。,箭头函数需要记着这句话:“箭头函数中没有 this 绑定,必须通过查找作用域链来决定其值,如果箭头函数被非箭头函数包含,则 this 绑定的是最近一层非箭头函数的 this,否则,this 为 undefined”。例 8 :

9

在函数内部使用 _this = this如果不使用 ES6,那么这种方式应该是最简单的不会出错的方式了,先将调用这个函数的对象保存在变量 _this 中,然后在函数中都使用这个 _this,这样 _this 就不会改变了。例 9:

10

在 func2 中,首先设置 var _this = this;,这里的 this 是调用 func2 的对象 a,为了防止在 func2 中的 setTimeout 被 window 调用而导致的在 setTimeout 中的 this 为 window。我们将 this(指向变量 a) 赋值给一个变量 _this,这样,在 func2 中我们使用 _this 就是指向对象 a 了。使用 apply、call、bind使用 apply、call、bind 函数也是可以改变 this 的指向的,原理稍后再讲,先来看一下是怎么实现的:使用 apply例 10:

11

使用 call例 11:

12

使用 bind例 12:

13

apply、call、bind 区别已经介绍了 apply、call、bind 都是可以改变 this 的指向的,但是这三个函数稍有不同。在 MDN 中定义 apply 如下;apply() 方法调用一个函数, 其具有一个指定的this值,以及作为一个数组(或类似数组的对象)提供的参数语法:

14

thisArg:在 fun 函数运行时指定的 this 值。需要注意的是,指定的 this 值并不一定是该函数执行时真正的 this 值,如果这个函数处于非严格模式下,则指定为 null 或 undefined 时会自动指向全局对象(浏览器中就是window对象),同时值为原始值(数字,字符串,布尔值)的 this 会指向该原始值的自动包装对象。argsArray:一个数组或者类数组对象,其中的数组元素将作为单独的参数传给 fun 函数。如果该参数的值为null 或 undefined,则表示不需要传入任何参数。从ECMAScript 5 开始可以使用类数组对象。浏览器兼容性请参阅本文底部内容。apply 和 call 的区别其实 apply 和 call 基本类似,区别只是传入的参数不同。call 的语法为:

15

所以 apply 和 call 的区别是 call 方法接受的是若干个参数列表,而 apply 接收的是一个包含多个参数的数组。例 13:例 14:

16

bind 和 apply、call 区别将刚刚的例子使用 bind 试一下

17

bind()方法创建一个新的函数, 当被调用时,将其this关键字设置为提供的值,在调用新函数时,在任何提供之前提供一个给定的参数序列。bind 是创建一个新的函数,必须要手动去调用:

推荐信息