首先,明确几个基本概念
- 严格模式和非严格模式,即是否添加'use strict'; this的行为结果不同,本文只讨论严格模式
let f=function(){
console.log(this);
}
f();
#严格模式下this为undefined,非严格模式为global对象
- 全局this在浏览器中指向window对象,在node中指向空对象,可以用如下代码测试
'use strict';
console.log(this);
- this一般存在于函数内部
- this为函数调用时所在对象的引用
let f=function () {
console.log(this);
};
let o={
name:'frank',
f:f
};
o.f();
#result
{ name: 'frank', f: [Function: f] }
- this指向的对象可以通过apply或call变更
let f=function (a,b) {
console.log(this);
};
let o={
name:'frank'
};
f.apply(o,[1,2]);
f.call(o,1,2);
#result
{ name: 'frank' }
{ name: 'frank' }
- Function.prototype.bind接收一个对象,并返回一个调用函数的拷贝,新函数的this指向该对象,在React中处理事件回调需要将bind绑定为组件对象,这样才可以调用this.setState方法
let f=function (a,b) {
console.log(this);
};
let o={
name:'frank'
};
let f1=f.bind(o);
f1();
#result
{ name: 'frank' }
- ES6箭头函数会自动传递this,而不改变this原来指向的对象,将4中的函数改为箭头函数,在React中也可以用箭头函数来避免使用bind
let f=()=>{
console.log(this);
};
let o={
name:'frank',
f:f
};
o.f();
#result,在node中运行,this默认指向{}
{}
#多层传递
let f=()=>{
console.log(this);
return ()=>{
console.log(this);
};
};
let o={
name:'frank',
f:f
};
o.f()();
#result
{}
{}
#改变默认this指向对象,并向下传递
let f=function(){
console.log(this);
return ()=>{
console.log(this);
};
};
let o={
name:'frank',
f:f
};
o.f()();
#result
{ name: 'frank', f: [Function: f] }
{ name: 'frank', f: [Function: f] }