在JavaScript中,this
关键字代表当前函数执行的上下文环境。它是一个非常重要的概念,经常用来解决程序中的“上下文”问题。但由于this
的指向不固定,所以很多开发者会因为混淆了this
的指向而导致程序运行出错。
this
关键字的指向是在函数被调用时动态绑定的,具体的指向既取决于调用函数的方式,也取决于函数执行时所处的上下文环境。下面让我们一起来看看this
的常见用例及其指向规则。
在JavaScript中,this
关键字的指向一般有五种常见的情形。
当一个函数在全局环境中被调用时,this
关键字会指向全局变量对象window
。
function test() {
console.log(this === window); // true
}
test();
在Node.js环境中,global
对象被作为一个全局对象使用。所以在Node.js环境中,以下代码片段将输出true
。
function test() {
console.log(this === global); // true
}
test();
当一个函数作为一个对象的方法被调用时,this
关键字会指向该对象。
var obj = {
name: "Jack",
sayName: function() {
console.log(this.name);
}
};
obj.sayName(); // Jack
当我们调用call
和apply
方法时,可以传入一个参数来指定函数执行时的this
关键字的指向。call
和apply
方法的不同之处在于它们对参数的处理方式。call
方法接受一个参数列表,而apply
方法接受一个以数组形式表示的参数列表。
function test() {
console.log(this.name);
}
var obj1 = {
name: "Jack"
};
var obj2 = {
name: "Tom"
};
test.call(obj1); // Jack
test.call(obj2); // Tom
当一个函数作为构造函数被调用时,通过new
运算符创建一个新的对象,并给this
关键字指向该新对象。
function Person(name) {
this.name = name;
}
var obj1 = new Person("Jack");
var obj2 = new Person("Tom");
console.log(obj1.name); // Jack
console.log(obj2.name); // Tom
在ES6新特性中引入的箭头函数中,this
关键字的指向基于其外部(即定义时)的上下文,在箭头函数内部无法改变其指向。因此,箭头函数中的this
指向与外部的上下文相同。
var obj = {
num: 2,
test: function() {
var arr = [1, 2, 3];
var multiple = arr.map((function(val) {
return val * this.num;
}).bind(this));
console.log(multiple); // [2, 4, 6]
}
};
obj.test();
在上面的例子中,我们使用了箭头函数的语法写了一个map方法的回调函数,在函数中使用了this.num
来访问obj
对象中的num
属性。由于箭头函数是在定义时就绑定了this
的指向,所以它可以正确地访问到obj
对象中的属性。
在JavaScript中,this
关键字的指向一般有五种常见的情形。正确区分这五种情形非常重要,可以让我们更好地解决程序中的上下文问题。