今天闲极无聊整理一下JavaScript中的this指向问题,希望对初学者有所帮助,大佬自动跳过
JEE:this指针又叫“上下文对象”,指向代码的执行环境对象 从以下几个常见场景归类
函数调用
当this出现在全局环境下的函数中,this指向宿主环境(浏览器下是window)
function sayName() {
this.name = '子落';
console.log(this.name);
}
sayName();//子落
在window环境下调用函数,this指向window对象,上面写法等同于
var name = '子落'
function sayName() {
//或者 name = '子落' (函数中声明变量时没有var,变量默认声明为全局变量)
console.log(this.name);
}
sayName();//子落
⚠️注意区分下面这种写法
function sayName() {
var name = '子落';
console.log(this.name);
}
sayName();ReferenceError资源不存在错误(由于在window对象中不存在name属性)
对象方法
当this出现在某个对象方法中时,this指向这个对象
var name = 'window';
var obj = {
name: '子落',
sayName: function() {
console.log(this.name)
}
};
obj.sayName() //子落
⚠️注意区分下面这种写法
var name = 'window';
var obj = {
name: '子落',
sayName: function() {
console.log(this.name);
}
};
var ss = obj.sayName;
ss(); //window
对象方法是在window环境下被当作函数调用,此时this指向window
构造函数
当this出现在构造函数中时,this指向新创建的对象实例
function Person() {
this.name = '子落'
}
//或者es6的class写法
class Person {
constructor() {
this.name = '子落'
}
}
var person = new Person();
console.log(person.name)//子落
call,apply,bind
当this出现在call,apply,bind等函数调用环境中时,this指向传入的第一个对象参数,不传时默认值是window
var name = 'window'
var person = {
name: '子落'
};
function sayName() {
console.log(arguments) //{ '0': 1, '1': 2, '2': 3 }
console.log(this.name)
}
sayName.apply(person) //子落(传递person作为执行环境,下同)
sayName.call(person) //子落
const say = sayName.bind(person, 1, 2, 3)
say() //子落
//不传参数是默认的执行环境是全局环境window
sayName.apply() //window
箭头函数
当this出现在箭头函数中时,this指向外层函数的执行环境
var name = 'this is window'
var person = {
name: '子落',
sayName: () => {
console.log(this.name)
},
hello() {
const bibao = () => {
console.log(this.name);
}
bibao()
}
}
person.sayName() //this is window
person.hello() //子落
顺便提一下箭头函数的几个特点:
- 无this指针;
- 无arguments;
- 不能作为构造函数;
- 函数内不能出现yield
特殊场景
除了上面列出的几种this指向,还有一些特殊场景,this总是指向window
匿名函数自调
var name = '子落';
var person ={
name : 'person子落',
showName : function(){
alert(this.name);
},
waitShowName : function(){
!function(__callback){
alert(this.name);
}();
}
};
person.showName() //person子落
person.waitShowName() //子落
定时任务(setTimeout、setInterval)
var name = '子落';
var person ={
name : 'person子落',
showName : function(){
alert(this.name);
},
waitShowName : function(){
setTimeout(function(){
this.showName();
}, 1000);
}
};
person.waitShowName(); //子落
⚠️注意,当定时任务传入的是一个箭头函数时,this并不会指向window
var name = 'this is window'
var person = {
name: '子落',
sayName() {
setTimeout(() => {
console.log(this.name)
}, 0)
}
}
person.sayName() //子落
//由于箭头函数本身没有this指针,箭头函数的this指针是外部函数的this指针(sayName)
//sayName是通过person对象调用的,所以this.name="子落"
综上可以总结:谁调用这个函数或方法,this关键字就指向谁