函数中的 this 是 JavaScript 中的难点之一. 根据 this 的英文词义, 有些人将 this 误解为指向自身, 但事实显然不会这么简单. 根据 this 的特性, 到 ES6 , this 总的来说有五种绑定情况. 下面我将这些情况 一 一 列举出来:
1. 默认绑定
默认绑定时, this 绑定全局对象. 如果函数调用时没有任何修饰符, 就会应用 this 的默认绑定. 这种情况很容易分辨, 具体看下方代码:
- function func() {console.log(this.c);
- }
- var c = 3;
- func() //3
代码中函数 func 的调用就是没有任何修饰符的调用, 这是 this 绑定全局对象, c 声明于全局作用域, 是全局对象的属性. 所以 c 可以通过 this.c 访问, 结果为 3 .
此外, 还应该注意严格模式与非严格模式的区别. 如果函数声明于严格模式中, 无论函数在何处执行, this 都不会绑定到全局对象. 此时通过 this 访问全局属性只会得到 undefined , 就像下方代码.
- "use strict"
- function func() {
- console.log(this.c);
- }
- var c = 3;
- func() //undefined
2. 隐式绑定
隐式绑定时, this 绑定上下文对象. 什么是上下文对象? 举个简单的例子:
- var obj = {num:2,
- func:con
- }
- function con() {
- console.log(this.num);
- }
- obj.func() // 2
在上方代码中, 一个对象内部包含一个函数, 通过对象引用属性而间接地引用了 con 函数. obj 就是 con 的上下文对象, this 隐式绑定到 obj , 所以 this.num 等于 2.
如果只是用 1 中的方式调用函数, 结果就变成了 undefined.
func() // 结果为 undefined
3. 显式绑定
显式绑定时, this 绑定到特定函数指定的对象. 有三个函数可以指定 this 绑定的对象, 分别为 apply,call,bind.JavaScript 中绝大部分函数都可以调用这三个方法, 方式也很简单:
- var obj = {a:1};
- function func(c,b) {
- console.log(this.a+c)
- }
- func.apply(obj,[1,2])
- func.call(obj,[1,2]);
- func.bind(obj,[1,2]);
三种方法的第一个参数都为 this 要绑定的对象, 第二个参数都为要传入的参数列表. apply 与 call 的区别为 ,call 函数可以传入多个参数列表. bind 函数与另外两种方法的区别为, 函数调用 apply 或 call 后会立即执行.
4. new 绑定
new 绑定时, this 绑定 new 构造的新对象. 代码如下:
- function func(num) {
- this.num = num;
- }
- var obj = new func(3);
- console.log(obj.num); // 3
obj 为 new 构造的新对象, 所以 this.num 即为 obj.num.
5. 箭头函数中 this 的绑定
箭头函数中, this 继承外层作用域的 this 绑定. 如果外层作用域 this 绑定一个对象, 箭头函数也绑定这个对象, 就像下方代码中所展示的:
- var obj = {
- nun: 1,
- func: function() {
- var boo = () = >{
- console.log(this.nun);
- }
- boo();
- }
- }
- obj.func(); //1
函数执行时, obj 是 func 的上下文对象, 所以 func 函数中的 this 绑定 obj 对象. 由于 func 函数是箭头函数的外层作用域, 所以箭头函数的 this 也绑定 obj 对象. 因此 this.nun = 1 , 函数执行结果为 1.
以上就是 JavaScript 中 this 五种绑定的完整总结. 当然, 实际代码中的 this 有各种各样让人迷惑的地方, 以后的文章会有相关介绍.
如果文章有帮助请点个喜欢支持一下.(_)
来源: http://www.jianshu.com/p/4c83008e8cd2