javaScipt中this的指向是动态的,是在运行时确定的,直接指向函数的调用对象。
全局函数中的this
function Person(name, age) {
console.log(this); // window
}
Person('Ian', 25);// 等同于window.Person('Ian', 25)
对象中的this
const obj = {
name: "Ian",
sayName: function () {
console.log(this.name);
},
};
obj.sayName(); // Output: "Ian"
const outerObj = {
name: "John",
innerObj: {
name: "Jane",
sayName: function () {
console.log(this.name);
},
},
};
outerObj.innerObj.sayName(); // Output: "Jane"
outerObj.innerObj.sayName()的实际调用者是outerObj.innerObj,所以this指向innerObj。
new 运算符中的this
this指向新创建的对象
function Person(name) {
this.name = name;
this.sayName = function () {
console.log(this.name);
};
}
const person1 = new Person("Ian");
person1.sayName(); // Output: "Ian"
在使用new操作符的时候,会自动创建一个新对象,并将this指向这个新对象。
箭头函数
箭头函数没有自己的this,它的this指向的是它外层作用域的this。
const book = {
title: "The Great Gatsby",
author: "F. Scott Fitzgerald",
getTitle: () => {
return this.title;
},
};
console.log(book.getTitle()); // undefined
getTitle()箭头函数的this指向外层作用域的this,即window。 在react中我们也经常使用箭头函数使this指向当前组件的实例, 或者使用bind将this指向组件实例。
class MyComponent extends React.Component {
constructor(props) {
super(props);
this.handleClick2 = this.handleClick2.bind(this);
}
handleClick = () => {};
handleClick2 (){}
render() {
return <button onClick={this.handleClick}>Click me</button>;
}
改变this指向
使用apply()、call()、bind()方法可以改变函数的this指向。
call(thsi, arg1, arg2, ...)方法可以改变函数的this指向为指定的对象,并传入参数。
const operations = {
num1: 1,
num2: 2,
add: function(num3 = 0, num4 = 0) {
return `result is: ${this.num1 + this.num2 + num3 + num4}`;
}
};
const obj2 = {
num1: 3,
num2: 4,
};
operations.add.call(obj2, 5, 6); // Output: "result is: 18"
bind函数改变this指向并返回一个新的函数,函数的参数可以放到前面也可以放到后面,当参数超过的时候从前往后选取。
operations.add.call(obj2, 5, 6); // Output: "result is: 18"
operations.add.bind(obj2, 5, 6)(); // Output: "result is: 18"
operations.add.bind(obj2, 5)(6,7); // Output: "result is: 18"
apply方法和call用法一致,唯一的区别是call方法接受一个参数列表,而apply方法接受一个参数数组。
operations.add.apply(obj2, [5, 6]); // Output: "result is: 18"