一文搞懂JavaScript中的this指向问题

1. 进入this的世界

this是JavaScript中的一个关键词,在不同的情况下代表的含义不同,由此引发了许多开发者的困惑。本文将从不同的角度介绍this指向的问题,希望能帮助大家理解JavaScript中的this指向。

2. this的指向规则

在JavaScript中,this的指向是运行时决定的,而不是写代码时决定的。在不同的环境下,this指向的对象也不同。

根据函数的调用方式不同,this会有不同的指向:

2.1 默认绑定

如果一个函数是独立调用的,那么这个函数中的this将会指向全局对象,在浏览器中就是window对象,在Node.js环境下就是global对象。这种情况被称为默认绑定。

var name = 'JavaScript';

function test() {

console.log(this.name); // 输出'JavaScript'

}

test();

上面代码中,test函数是独立调用的,所以在函数内部,this指向的是全局对象window,this.name指的就是全局变量name。

2.2 隐式绑定

如果一个函数是作为对象的方法调用的,那么这个函数中的this将会指向调用它的对象,称为隐式绑定。

var person = {

name: 'Tom',

sayName: function() {

console.log(this.name);

}

};

person.sayName(); // 输出'Tom'

上面代码中,sayName()函数是作为对象person的方法调用的,所以函数内部的this指向的是对象person,this.name指的是对象person的属性name。

2.3 显式绑定

可以通过JavaScript内置的函数apply、call和bind,来指定函数内部的this指向的对象。这就是显式绑定。

var person1 = {

name: 'Tom'

};

var person2 = {

name: 'Jerry'

};

function sayName() {

console.log(this.name);

}

sayName.call(person1); //输出'Tom'

sayName.apply(person2); //输出'Jerry'

可以看到,sayName函数通过call和apply方法调用时,this分别被绑定到了person1和person2对象上。

2.4 new绑定

如果使用new操作符调用一个函数,那么这个函数中的this会被自动绑定到新创建的对象上。

function Person(name) {

this.name = name;

}

var person = new Person('Tom');

console.log(person.name); //输出'Tom'

在上面的代码中,当使用new操作符调用Person函数时,Person内部的this被自动绑定到新创建的对象上,并且对象的属性name被赋值为'Tom'。

3. this指向的问题

this指向的问题在JavaScript中很常见,如果没有理解清楚this的指向规则,就很容易出现问题。

3.1 this指向window对象

function sayName() {

console.log(this.name);

}

var name = 'JavaScript';

sayName();

在上面的代码中,由于sayName()函数是独立调用的,所以函数内部的this被默认绑定到了全局对象window上,this.name指向的是全局变量name。

3.2 this指向函数对象

var person = {

name: 'Tom',

sayName: function() {

console.log(this.name);

}

};

var fn = person.sayName;

fn();

在上面的代码中,虽然person对象中的方法sayName被赋值给了变量fn,但是调用fn时,函数内部的this并不会指向person对象,而是指向函数本身。因此在函数内部无法得到person对象中的属性name。

3.3 使用bind绑定this

可以使用JavaScript内置的函数bind,在调用一个函数时,将函数内部的this指向指定的对象。

var person = {

name: 'Tom',

sayName: function() {

console.log(this.name);

}

};

var fn = person.sayName.bind(person);

fn();

在上面的代码中,使用bind将sayName函数中的this绑定到person对象上,并将新的函数赋值给变量fn,调用fn时可以正确输出person对象中的属性name。

3.4 链式调用中的this指向

var obj = {

value: 1,

getValue: function() {

console.log(this.value);

return this;

},

add: function(n) {

this.value += n;

return this;

},

minus: function(n) {

this.value -= n;

return this;

}

};

obj.getValue().add(2).minus(1).getValue();

在上面的代码中,getValue、add和minus方法都返回了对象本身,这样就可以实现链式调用,减少代码的书写量。在链式调用中,每个方法内部的this都要指向前一个方法返回的对象。因此通过这种方式实现的链式调用,可以让代码更加简洁易懂。

4. 总结

this是JavaScript语言中非常重要的一个概念,它的指向是在函数执行时动态确定的,需要根据不同的调用方式进行判断和理解。在实际开发中,遇到this指向问题时,要清楚地分析函数执行的上下文,根据this的指向规则来找到问题所在,并正确地绑定this指向。

免责声明:本文来自互联网,本站所有信息(包括但不限于文字、视频、音频、数据及图表),不保证该信息的准确性、真实性、完整性、有效性、及时性、原创性等,版权归属于原作者,如无意侵犯媒体或个人知识产权,请来电或致函告之,本站将在第一时间处理。猿码集站发布此文目的在于促进信息交流,此文观点与本站立场无关,不承担任何责任。