this指向问题网上可以找到很多文章,自己梳理了一下方便以后的查看。
普通函数
总结:普通函数中,this在定义的时候是不明确的,调用的时候才能确定,指向调用他的对象。
普通函数中常见的几种情况(都是非严格模式下):
例子1(函数自执行):
var a = 123;
function num() {
var a = 10;
console.log(this.a); //123
console.log(this); // window
}
num(); // 此时等于window.num(),window调用了num(), 所以指向window
例子2(对象调用函数):
var name = 'eric';
var person = {
name: 'hammer',
fn: function () {
console.log(this.name);
}
}
person.fn(); // hammer,person对象调用
例子3(赋值)
var a = 10;
var obj = {
a: 20,
fun: function () {
console.log(this.a)
}
}
obj.fun(); //20 ,this指向obj对象
var funOut = obj.fun;
funOut(); //10 ,全局变量所以此时的this指向window
例子4:
var a = 1
var obj = {
a: 2,
test: function () {
function fn() {
console.log(this.a)
}
return fn()
}
}
obj.test() // 1. 这里的fn是用return方法返回的,并没有被其它对象直接调用,普通函数里this也并不会被继承,所以这里的this指向全局的window。
例子5(事件函数里的this指向事件源,如果事件函数里有普通函数,函数自执行后内部this还是指向window)
document.body.onclick = function(){
console.log(this); //body对象
function fn(){
console.log(this); //Window
}
fn(); //函函数自执行时,内部的this指向顶层对象/window
};
例子6(构造函数):
function CreatPerson() {
this.name = "李伟";
console.log(this);
console.log(this.name);
}
//构造函数中的this指向了创建出的对象
//new关键字会在内存中开辟一块空间,这个空间在设置好值后会把地址交给per1这个变量,所以per1就是创建出来的对象的“代言人”,而空间存在的“this”,也就指向了per1;
var per1 = new CreatPerson(); //CreatPerson{} 李伟
常见的一些普通函数的this指向面试题涉及的知识都整理到这了。
箭头函数
箭头函数不会创建自己的this,它只会从自己的作用域链的上一层继承this
箭头函数不能使用call()、apply()、bind()等方法直接修改箭头函数内的this,箭头函数在创建时已经确定了指向。
var name = 'eric';
var person = {
name: 'hammer',
fn: () => {
console.log(this.name);
},
fn1: function () {
console.log(this.name)
}
};
person.fn(); //eric
person.fn1() //hammer
setTimeout
对于setTimeout,setInterval这种匿名函数,默认情况下this是指向window的。
如下
var name = 'hammer';
var obj = {
name: "小王",
func2: function () {
setTimeout(function () {
console.log(this) //setTimeout匿名函数this指向了window。
}, 100);
}
}
obj.func2() // window。
使用箭头函数
var name = 'hammer';
var obj = {
name: "小王",
func2: function () {
setTimeout(() => {
console.log(this); //obj 箭头函数setTimeout从作用域链的上一层继承this
console.log(this.name) // 小王
}, 100);
}
}
obj.func2()