平时开发过程中,虽然都是用hooks或者composition api,但是this在JS中还是非常重要的东西,并且其规则也是容易混淆。
1. 普通函数
解析器在调用函数时每次都会向函数内部传递进一个隐含的参数 这个隐含的参数就是this,this指向的是一个对象 这个对象是函数执行的上下文对象,调用该函数的上下文对象 根据函数的调用方式的不同,this会指向不同的对象
- 以函数的形式调用时,this指向的是window
- 以方法的形式调用时,this指向的是调用方法的那个对象
window.color='red'
let obj = {
color:'blue',
sayColor:sayColor
}
function sayColor(){
console.log(this.color)
}
sayColor(); //'red'
obj.sayColor //'blue'
function Obj() {
a = 1
fun = function() {
console.log(this)
}
console.log(this) //obj
fun() //window
}
const obj = new Obj()
2. 箭头函数
在箭头函数中,this指向的是定义箭头函数的上下文 当事件回调或定时回调中调用某个函数时,this指向的并非想要的对象, 这时就可以将回调函数写成箭头函数便可解决问题。比如定时器 setTimeout
window.color = 'red'
let sayColor = () => console.log(this.color)
let obj = {
color: 'blue',
sayColor:sayColor
}
sayColor(); //'red'
obj.sayColor(); //'red'
function Obj() {
a = 1
fun = () => {
console.log(this)
}
console.log(this) //obj
fun() //obj
}
const obj = new Obj()
题目1
var name = "window";
var person = {
name: "person",
sayName: function () {
console.log(this.name);
}
};
function sayName() {
var sss = person.sayName;
sss(); // window
person.sayName(); //person
(person.sayName)(); //person
(b = person.sayName)(); //window
}
sayName();
这个主要是(person.sayName)()和(b = person.sayName)()
(person.sayName)()在解析过程中就是拿到sayName方法调用,所以结果就是person
而(b = person.sayName)()由于有一个赋值表达式,所以等价于
(b = person.sayName)()
// 等价于⬇
b = person.sayName
b()
作为独立函数调用,所以this指向window
题目2
var name = 'window'
function Person (name) {
this.name = name
this.obj = {
name: 'obj',
foo1: function () {
return function () {
console.log(this.name)
}
},
foo2: function () {
return () => {
console.log(this.name)
}
}
}
}
var person1 = new Person('person1')
var person2 = new Person('person2')
person1.obj.foo1()() // window
person1.obj.foo1.call(person2)() // window
person1.obj.foo1().call(person2) // person2
person1.obj.foo2()() // obj
person1.obj.foo2.call(person2)() // person2
person1.obj.foo2().call(person2) // obj
就是注意一下箭头函数是不绑定this的,会去上层作用域去寻找this,所以这里面调用foo2的函数得到的箭头函数都是指向foo2的this值。