this指向总结
前言
作为JS中最难理解的知识点之一,很多时候都很难分清到底指向的是啥,学了很久都还是处于一种云里雾里的状态。但又作为面试必考知识点之一,能够把这个问题研究透彻,对我们以后无论是面试还是工作都有很大用处。这次对this的使用方式做一个总结。
在构造函数中
let name='window'
function Person(name,age){
this.name=name;
this.age=age
}
let man=new Person('hkj',21)
console.log(man.name) //hkj
对于new这种方式来说,this将永远绑定到被实例化的对象上
直接调用
var name='window'
function fun(){
var name="name"
console.log(this.name)
}
fun() //window
var name='window'
function fun(){
var name='fun'
console.log(this.name)
}
let obj={
fun:fun,
name:'hkj'
}
let f=obj.fun
f() //window
var name='window'
function hello(){
var name='hello'
console.log(this.name)
}
let obj1={
name:'obj1',
hello
}
let obj2={
name:'obj2',
obj1
}
let fun=obj2.obj1.hello;
fun() //window
对于这直接调用方法来说,最后只要类似fun()这种调用,this最后都指向window
箭头函数
var name='hkj'
function fun(){
var name="hkj1"
return ()=>{
var name='hkj2'
console.log(this.name) //hkj
return ()=>{
var name='hkj3'
console.log(this.name) //hkj
}
}
}
fun()()()
无论嵌套多少层箭头函数中的this与最外层非箭头函数this相同,最外层非箭头函数为fun(),其中的this指向window所以里面两个箭头函数也一样。
当做属性调用
var name='window'
function fun(){
var name='fun'
console.log(this.name)
}
let obj={
fun:fun,
name:'hkj'
}
obj.fun() //hkj
被当做属性调用时,函数中this指向对最后一个调用函数的对象。这里指向obj,所以name为hkj
var name='window'
function hello(){
var name='hello'
console.log(this.name)
}
let obj1={
name:'obj1',
hello
}
let obj2={
name:'obj2',
obj1
}
obj2.obj1.hello() //obj1
这里引用了多层,但用上面的方法判断,hello()前面是obj1,所以this指向obj1,最后name为obj1
定时器内this指向
var name='window'
function hello(){
setTimeout(function(){
console.log(this.name)
}, 100);
}
let obj={
name:'obj',
hello
}
obj.hello() //widow
var name='window'
function hello(){
console.log(this.name)
}
let obj={
name:'obj',
hello
}
setTimeout(obj.hello,1000) //window
按照上一种情况来说,此时的this应该指向的是obj,但setTimeout是一种特殊情况,setTimeout中的this都指向window。
解决办法:改为箭头函数,在setTimeout外层将this赋值给其他变量然后传入,或者call,aplly,bind等
- 引用官方解释

call,apply,bind改变this指向
绑定优先级
new>call及其他两个函数>属性调用>直接调用
转载自:https://juejin.cn/post/6844903806510039047