详解JS中的this

首先,明确几个基本概念

  1. 严格模式和非严格模式,即是否添加'use strict'; this的行为结果不同,本文只讨论严格模式
let f=function(){
  console.log(this);
}
f();
#严格模式下this为undefined,非严格模式为global对象
  1. 全局this在浏览器中指向window对象,在node中指向空对象,可以用如下代码测试
'use strict';
console.log(this);
  1. this一般存在于函数内部
  2. this为函数调用时所在对象的引用
let f=function () {
  console.log(this);
};
let o={
  name:'frank',
  f:f
};
o.f();

#result
{ name: 'frank', f: [Function: f] }
  1. 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' }
  1. 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' }
  1. 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] }

推荐阅读更多精彩内容