this全面解析

2019-12-06  本文已影响0人  唐井儿_
1 定义

谁调用的函数,该函数的this就指向谁。

2 四种绑定规则

2.1 默认绑定,this指向全局对象,严格模式下绑定到undefined

var a = 1;
function foo() {
  console.log(this.a);
}
foo(); // 1

2.2 隐式绑定,this绑定到调用函数的上下文对象上

function foo() {
  console.log(this.a);
}
var a = 1;
var obj = {
  a: 2,
  foo: foo // 核心!
};
obj.foo(); // 2
// 情况一
function foo() {
  console.log(this.a);
}
var a = 'I`m in global scope!';
var bar = {
  a: 'I`m in bar`s scope!',
  foo:foo
};
var copyFoo = bar.foo; // 核心!重新赋值到另一变量上。copyFoo是bar.foo的一个引用,实际上,引用的是foo本身
copyFoo(); // 'I`m in global scope!'

// 情况二
function foo() {
  console.log(this.a);
}
function doFoo(fn) {
  fn();
}
var a = 'I`m in global scope!';
var bar = {
  a: 'I`m in bar`s scope!',
  foo:foo
};
// 函数传递是一种隐式赋值,所以结果和上例一样
doFoo(bar.foo); // 'I`m in global scope!'
setTimeout(bar.foo, 100); // 'I`m in global scope!'

2.3 显式绑定,使用apply/call方法,显式绑定到指定对象上

function foo() {
  console.log(this.a);
}
var bar = {
  a: 'I`m in bar`s scope!'
};
foo.call(bar); // 'I`m in bar`s scope!'
function foo() {
  console.log(this.a);
}
function doFoo(fn, context) {
  return function () { // 核心!
    fn.apply(context, arguments);
  }
}
var a = 'I`m in global scope!';
var bar = {
  a: 'I`m in bar`s scope!',
  foo:foo
};

doFoo(bar.foo, bar)(); // 'I`m in bar`s scope!'
setTimeout(doFoo(bar.foo, bar), 100); // 'I`m in bar`s scope!'

// 此模式很有用,于是es5提供了内置的方法Function.prototype.bind,用法如下:
setTimeout(bar.foo.bind(bar), 100); // 'I`m in bar`s scope!'
function Foo(a) {
  this.a = a;
}
var fooInstantiation = new Foo('1');
fooInstantiation .a; // '1'
3 优先级

new绑定 > 显示绑定 > 隐式绑定 > 默认绑定

4 被忽略的this

有些调用需要使用默认绑定规则,如果想“更安全”地忽略this绑定,可以用Object.create(null)

Math.max.apply(Object.create(null), [1, 3]);
5 特殊的箭头函数

箭头函数并不会使用上边的四条规则,而是根据词法作用域来决定this。也就是说箭头函数会继承外层函数调用的this绑定,就和es6之前的self = this机制一样

function foo() {
  setTimeout(() => {
    console.log(this.a);
  }, 0);
}
var a = 1;
var obj = {a: 2};
foo.call(obj); // 2

function foo2() {
  var self = this;
  setTimeout(function() {
    console.log(self.a);
  }, 0);
}
foo2.call(obj); // 2

参考《你不知道的JavaScript》上卷 / Simpson, K.

上一篇下一篇

猜你喜欢

热点阅读