近日准备面试,苦于 this 指向问题没搞清楚;查阅过后简单总结一下:
- 普通函数 this 指向与函数的调用者密切相关;this 总是指向函数的调用者;
- 普通函数,this 指向全局window
- 立即执行函数中,this 指向全局 window
- 定时器函数中,this 指向全局 window
- 构造函数中,this 指向 new 出来的实例化对象
- 对象中,this 指向该函数所属的对象
- dom 节点绑定事件中,this 指向绑定事件 dom 节点对象
- 箭头函数 this 指向仅仅是发生在定义时候,后续不可再修改;
- 定义箭头函数的时候,若外部有普通函数包裹则 this 指向与外部普通函数 this 指向一致,
- 若没有则默认指向 window
上例子简单解释以上两点
const func = function(){
console.log(this);
}
func() // window 直接调用,this 指向 window
let obj = {
x:1,
func:function(){
console.log(this); // obj func 被 obj 调用 this 指向 obj
(()=>{
console.log(this); // obj 箭头函数,外部存在函数 this 指向与外部函数指向一致;外部函数 this 指向 obj
})()
const func1 = function(){
console.log('func1',this);// window 直接调用,this 指向 window
(()=>{
console.log('func1箭头函数',this); // 箭头函数,外部存在函数 this 指向与外部函数指向一致;外部函数 this 指向 window
})()
}
func1()
},
func1:()=>{
console.log(this); // window 箭头函数,外部没有函数包裹 this 指向 window
}
}
obj.func()
obj.func1()
const func1 = function(){
const func2 = function(){
console.log(this);//直接调用,this 指向 window
const func3 = function(){
console.log(this);//直接调用,this 指向 window
}
func3()
}
func2()
}
func1()
更改this指向方法
bind、call、apply
- call 第一个参数为绑定对象,后续为函数参数
function fn(val, num) {
this.val = val;
this.num = num;
}
const obj1 = {}
// 经过call,this指向obj1,obj1开始有val、num属性
fn.call(obj1, '修改this指向', 100)
console.log(obj1);
// 以下this均指向window,val:undefined,num:undefined
fn.call()
fn.call(null)
fn.call(undefined)
- bind 返回一个函数,需要添加 () 执行;且只会绑定一次:链式bind 只认第一次绑定的对象
function fn(val, num) {
this.val = val;
this.num = num;
}
const obj1 = {}
fn.bind(obj1, '修改this指向', 100)()
- apply ,第一个参数为绑定对象,后续参数通过数组传入
function fn(val, num) {
this.val = val;
this.num = num;
}
const obj1 = {}
// 经过apply,this指向obj1,obj1开始有val、num属性
fn.apply(obj1, ['修改this指向', 100])
// 以下this均指向window,val:undefined,num:undefined
fn.apply()
fn.apply(null)
fn.apply(undefined)