默认调用 对象调用 call apply调用

 1.函数在调用时,JavaScript会默认给this绑定一个值;  2.this的 绑定和定义的位置(编写的位置) 没有关系;  3.this的绑定和调用方式以及调用的位置有关系;  4.this是在运行时被绑定的;

判断this

现在我们可以根据优先级来判断函数在某个调用位置应用的是哪条规则。可以按照下面的

顺序来进行判断:

  1. 函数是否在new 中调用(new 绑定)?如果是的话this 绑定的是新创建的对象。

var bar = new foo()

  1. 函数是否通过call、apply(显式绑定)或者硬绑定调用?如果是的话,this 绑定的是

指定的对象。

var bar = foo.call(obj2)

  1. 函数是否在某个上下文对象中调用(隐式绑定)?如果是的话,this 绑定的是那个上

下文对象。

var bar = obj1.foo()

  1. 如果都不是的话,使用默认绑定。如果在严格模式下,就绑定到undefined,否则绑定到

全局对象。

var bar = foo()

就是这样。对于正常的函数调用来说,理解了这些知识你就可以明白this 的绑定原理了。

不过…凡事总有例外。

如果要判断一个运行中函数的this 绑定,就需要找到这个函数的直接调用位置。找到之后
就可以顺序应用下面这四条规则来判断this 的绑定对象。

  1. 由new 调用?绑定到新创建的对象。
  2. 由call 或者apply(或者bind)调用?绑定到指定的对象。
  3. 由上下文对象调用?绑定到那个上下文对象。
  4. 默认:在严格模式下绑定到undefined,否则绑定到全局对象。

一定要注意,有些调用可能在无意中使用默认绑定规则。如果想“更安全”地忽略this 绑
定,你可以使用一个DMZ 对象,比如ø = Object.create(null),以保护全局对象。
ES6 中的箭头函数并不会使用四条标准的绑定规则,而是根据当前的词法作用域来决定
this,具体来说,箭头函数会继承外层函数调用的this 绑定(无论this 绑定到什么)。这
其实和ES6 之前代码中的self = this 机制一样。


在JavaScript中,this的行为由语言规范定义,而V8等引擎通过内部机制实现这些规则。以下是this的关键点及引擎处理的解析:

一、this的绑定规则

  1. 默认绑定

    • 非严格模式:全局对象(如windowglobal)。
    • 严格模式:undefined
    function foo() { console.log(this); }
    foo(); // 全局对象(非严格)或 undefined(严格)
  2. 隐式绑定

    • 函数作为对象方法调用时,this指向该对象。
    const obj = { foo() { console.log(this); } };
    obj.foo(); // obj
  3. 显式绑定

    • 使用callapplybind强制设置this
    function foo() { console.log(this); }
    foo.call({ a: 1 }); // { a: 1 }
  4. new绑定

    • 构造函数中,this指向新创建的对象实例。
    function Foo() { this.x = 1; }
    const instance = new Foo(); // this → instance
  5. 箭头函数

    • 词法作用域决定this,继承外层非箭头函数this
    const obj = {
      foo: () => console.log(this), // 外层作用域的this(如全局对象)
    };
    obj.foo();

二、V8引擎的内部处理

  1. 执行上下文this的解析

    • 每次函数调用会创建**执行上下文**,其中包含this的值。
    • 引擎根据调用方式(方法、构造函数等)动态确定this
  2. 词法分析阶段的处理

    • 箭头函数在解析时捕获外层this,存储为词法环境的一部分。
    • 普通函数在调用前this未确定,依赖调用时的上下文。
  3. 优化策略

    • 内联缓存(Inline Caching):对频繁调用的方法缓存this的类型,减少查找开销。
    • 隐藏类(Hidden Classes):优化对象属性的访问,间接加速this相关操作。
  4. 严格模式的处理

    • 函数内部若启用严格模式(通过"use strict"),引擎会将未绑定的this设为undefined,而非默认的全局对象。
  5. 显式绑定的底层实现

    • call/apply直接修改调用帧中的this值。
    • bind生成包裹函数,闭包保存预设的this,调用时直接传递。

三、宿主环境的影响

  • 浏览器/DOM事件:事件处理函数中的this通常指向触发元素,由DOM API设置,非引擎行为。
  • Node.js模块:顶级this指向模块的exports对象,而非全局对象。

四、总结

  • 动态性:普通函数的this在调用时动态确定,依赖调用方式。
  • 词法性箭头函数this在定义时静态捕获,不受调用方式影响。
  • 引擎优化:V8通过内联缓存、隐藏类等技术高效管理this,提升性能。
  • 规范遵循:严格模式、显式绑定等行为严格遵循ECMAScript标准。

理解this需结合语言规范与引擎实现机制,同时注意宿主环境(如浏览器)的扩展行为。