文章

ES5和ES6的this

ES5和ES6的this

普通函数和箭头函数的 this

还是一道经典题目,下面的这段代码的输出是什么?(为了方便解释,输出放在了注释中)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
function fn() {
    console.log(this); // 1. {a: 100}
    var arr = [1, 2, 3];

    (function () {
        console.log(this); // 2. Window
    })();

    // 普通 JS
    arr.map(function (item) {
        console.log(this); // 3. Window
        return item + 1;
    });
    // 箭头函数
    let brr = arr.map((item) => {
        console.log("es6", this); // 4. {a: 100}
        return item + 1;
    });
}
fn.call({ a: 100 });

其实诀窍很简单,常见的基本是 3 种情况:es5 普通函数、es6 的箭头函数以及通过bind改变过上下文返回的新函数。

es5 普通函数

  • 函数被直接调用,上下文一定是window
  • 函数作为对象属性被调用,例如:obj.foo(),上下文就是对象本身obj
  • 通过new调用,this绑定在返回的实例上

es6 箭头函数: 它本身没有this,会沿着作用域向上寻找,直到global / window。请看下面的这段代码:

1
2
3
4
5
6
7
8
9
10
11
12
function run() {
    const inner = () => {
        return () => {
            console.log(this.a);
        };
    };

    inner()();
}

run.bind({ a: 1 })(); // Output: 1

bind 绑定上下文返回的新函数:就是被第一个 bind 绑定的上下文,而且 bind 对“箭头函数”无效。请看下面的这段代码:

1
2
3
4
5
6
7
8
9
function run() {
    console.log(this.a);
}

run.bind({ a: 1 })(); // output: 1

// 多次bind,上下文由第一个bind的上下文决定
run.bind({ a: 2 }).bind({ a: 1 })(); // output: 2

最后,再说说这几种方法的优先级:new > bind > 对象调用 > 直接调用

至此,这道题目的输出就说可以解释明白了。

本文由作者按照 CC BY 4.0 进行授权