在JavaScript中,this关键字是一个对象,它根据函数的调用方式不同而发生变化。在定义函数的时候我们通常称之为上下文,然后在执行函数的时候确定它的上下文。
this指向在JavaScript中是非常灵活的。一般情况下它指向的是调用函数的对象,但是在一些情况下它的行为会非常变态。下面我们来详细讲解JavaScript中this的指向。
在全局作用域中使用this是非常简单的,它会指向全局对象——window(浏览器中)或者global(Node.js中)。
console.log(this); // window (浏览器环境)
在函数作用域中使用this的指向有很多情况,分别对应不同的函数调用方式。
当直接调用函数时,this会指向全局对象。
function foo() {
console.log(this);
}
foo(); // window (浏览器环境)
当作为对象的方法调用时,this指向的是调用这个方法的对象。
let obj = {
name: 'MonkeyKing',
showName: function() {
console.log(this.name);
}
}
obj.showName(); // MonkeyKing
当使用构造函数创建对象时,this将指向新创建的对象。
function Person(name) {
this.name = name;
}
let p1 = new Person('Allen');
console.log(p1.name); // 'Allen'
通过call和apply调用时,this指向的是传入的第一个参数。
function foo() {
console.log(this.name);
}
let obj1 = { name: 'Allen' };
let obj2 = { name: 'Bob' };
foo.call(obj1); // Allen
foo.apply(obj2); // Bob
箭头函数中的this和包含箭头函数的上一层作用域中的 this 指向是一样的。
function Person(name) {
this.name = name;
return () => console.log(this.name);
}
let p1 = new Person('Allen');
let p2 = new Person('Bob');
let getName1 = p1();
let getName2 = p2();
getName1(); // Allen
getName2(); // Bob
如果要在函数定义时就指定this的指向,可以使用bind、call和apply方法。其中bind返回一个新的函数,call和apply直接调用函数。
function foo() {
console.log(this.name);
}
let obj1 = { name: 'Allen' };
let obj2 = { name: 'Bob' };
let bindFoo = foo.bind(obj1);
bindFoo(); // Allen
foo.call(obj2); // Bob
foo.apply(obj1); // Allen
本文详细讲解了JavaScript中this的指向和绑定。this指向在JavaScript中非常灵活,可以说是很难掌握的部分。如果想要深入学习JavaScript,必须要彻底掌握this的指向和绑定。
示例1:
// 定义一个计算器对象
let calculator = {
num1: 0,
num2: 0,
setNum(num1, num2) {
this.num1 = num1;
this.num2 = num2;
},
add() {
return this.num1 + this.num2;
},
subtract() {
return this.num1 - this.num2;
}
}
// 设置计算器的两个数
calculator.setNum(2, 3);
// 进行加减运算
console.log(calculator.add()); // 5
console.log(calculator.subtract()); // -1
示例2:
let person1 = {
name: 'Allen',
age: 20,
greet: function() {
console.log('Hello ' + this.name);
}
}
let person2 = {
name: 'Bob',
age: 30
}
// 在person2上调用person1的greet方法
person1.greet.call(person2); // 'Hello Bob'
本文链接:http://task.lmcjl.com/news/8455.html