js中this的指向问题
常见的大概有以下几种情况:
- 全局作用域、普通函数以及定时器中的this指向全局对象window
- 方法中的this指向的是调用它的对象
- 构造函数中的this指向构造函数的实例
- 箭头函数中没有绑定this,this为最近外层作用域下有定义的this
- call、apply、bind可改变this指向
对以下代码进行说明,加深理解:
- 全局作用域、普通函数以及定时器中的this指向全局对象window
//定义全局变量
var name = 'js'; //相当于window.name = 'js'
console.log(this.name); //js
console.log(window.name); //js
console.log(this === window); //ture
//定时器中的this
setTimeout(function(){
console.log(this.name)
}, 1000); //1秒后打印出js;相当于执行了window.setTimeout()
//普通函数中的this
function f1(){
return this.name;
}
f1() === 'js'; //ture,相当于执行window.f1();
- 方法中的this指向的是调用它的对象
var obj = {
num: 37,
f: function() {
return this.num;
}
};
console.log(obj.f()); // 37; obj对象调用f方法
- 构造函数中的this指向构造函数的实例
function parent(name,age) {
this.name = name;
this.age = age;
}
var child = new parent('js',18);
console.log(child.name); //js
console.log(child.age); //18
- 箭头函数中没有绑定this,this为最近外层作用域下有定义的this
var globalObject = this;
var foo = (() => this);//最近的外层作用域为全局对象
console.log(foo() === globalObject); // true
//箭头函数
var name = 'js1';
var obj = {
name:'js2',
fn:()=>this.name
}
console.log(obj.fn()); //js1
//非箭头函数
var name = 'js1';
var obj = {
name:'js2',
fn:function() {
return this.name
}
}
console.log(obj.fn()); //js2
- call、apply、bind可改变this指向
var name = 'Global';
var obj = { name: 'js' };
function whatsThis(arg) {
return this.name; // this的值取决于函数的调用方式
}
whatsThis(); // Global
whatsThis.call(obj); // js
whatsThis.apply(obj); // js
// 将一个对象作为call和apply的第一个参数,this会被绑定到这个对象。
附:字节跳动面试题
var name = 'Global';//若无此定义,则window.name为undefined
var obj = {
name: 'js',
fn: function() {
return this.name
}
};
const fn1 = obj.fn;
const fn2 = fn1;
console.log(fn2()); //Global
console.log(fn2.call(obj)); //js
注:以上是个人学习js中的this的一些总结,为了方便理解,只列举了一些比较常见的场景,前端笔试或面试题中关于this指向的问题千变万化,大家可以多找一些复杂的题目加深对知识点理解,若有错误欢迎指正!
参考文档:MDN文档中的this关键字