首页 > 代码库 > this

this

一、this的绑定

This是在运行时进行绑定的。并不是在编写时绑定的,他的上下文取决于函数调用时的各种条件。this的绑定与函数声明的位置没有任何关系,只取决于函数的调用方式。

二、this是什么

当一个函数被调用时,会创建一个活动记录(执行上下文)。这个记录会包含函数在哪里被调用、函数的调用方法、传入的参数等信息。this就是记录的其中的一个属性,会在函数执行过程中用到。 

三、this的绑定规则

我们可以根据优先级来判断函数在某个调用位置应用的是哪条规则。可以按照下面的顺序来进行判断:
  1. 函数是否在new中调用(new绑定)?如果是的话this绑定的是新创建的对象。
         var bar = new foo()
  2. 函数是否通过call、apply(显式绑定)或者硬绑定调用?如果是的话,this绑定的是指定的对象。
         var bar = foo.call(obj2)
  3. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this绑定的是那个上下文对象。
         var bar = obj1.foo()
  4. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到全局对象(window)。
         var bar = foo()
就是这样。对于正常的函数调用来说,理解了这些知识你就可以明白 this 的绑定原理了。
demo:https://codepen.io/psword/pen/BZLgZX

四、注意

4.1、显示绑定

function foo() {
      console.log(‘this:‘this); // Number(2)
   }
foo.call( 2 );
 
 
虽然foo是一个引用,但是实际上,它引用的是foo函数本身,因此此时的foo()实际上是一个不带有任何修饰的函数调用,因此应用了默认绑定。
对于显式绑定,如果传入的是一个原始值(字符串类型,布尔类型或者数字类型)来当做this的绑定对象,这个原始值会被转换为它的对象形式,这通常被称为装箱。
另外,当null或者undefined作为this的绑定对象传入call、apply或者bind,这些值在调用时会被忽略,实际应用的是默认绑定规则。

4.2、间接引用

 
 
函数在间接引用时,调用这个函数会应用默认绑定规则。
间接引用最容易在赋值时发生:
 
 
function foo() {
       console.log(‘a: ‘this.a); // Number(2)
 }
 
var a = "global";
var obj = {
   a:  "part",
   foo:  foo
};
var p = { a: 2};
(p.foo = obj.foo)(); // global
p.foo(); // 2
 
 
赋值表达式p.foo = obj.foo的返回值是目标函数的引用,因此调用位置是foo()而不是p.foo()或者o.foo()。这里会应用默认绑定
这里关键是看到底是谁在调用函数。

this