自学内容网 自学内容网

js进阶——this全面解析

全面解析 this 关键字

在 JavaScript 中,this 是一个经常让初学者困惑的概念。this 的值取决于函数的调用位置,而不是它定义的位置。因此,理解调用位置和不同的绑定规则非常重要。接下来我们详细讲解 this 的各个方面。

1. 调用位置

this 的绑定取决于调用位置,即函数被调用的上下文环境。调用位置是决定 this 如何绑定的关键。

function show() {
  console.log(this);
}

show(); // 在全局环境中调用,this 默认绑定到全局对象 (浏览器中为 window)
2. this 绑定规则
2.1 默认绑定

默认绑定是最基本的规则。在非严格模式下,如果函数直接调用,this 将绑定到全局对象(在浏览器中是 window)。在严格模式下(use strict),this 会绑定为 undefined

function foo() {
  console.log(this); 
}

foo(); // 非严格模式下 this 是 window,严格模式下 this 是 undefined
2.2 隐式绑定

当函数作为对象的方法调用时,this 会被绑定到该对象。也就是说,调用该函数的对象是 this 的值。

const obj = {
  name: 'Alice',
  show() {
    console.log(this.name);
  }
};

obj.show(); // 输出 'Alice', this 绑定到 obj
2.3 显示绑定

通过 callapplybind 方法,可以手动指定 this 的值,这称为显示绑定

  • call:直接调用函数并指定 this
  • apply:类似于 call,但传递参数是以数组形式。
  • bind:返回一个新的函数,并永久绑定 this
function greet() {
  console.log(this.name);
}

const person = { name: 'Bob' };

greet.call(person); // 显式绑定 this,输出 'Bob'
greet.apply(person); // 输出 'Bob'
const boundGreet = greet.bind(person);
boundGreet(); // 输出 'Bob'
2.4 new 绑定

当通过 new 关键字调用函数时,会创建一个新的对象,并且这个对象会绑定到 this。同时,新创建的对象会被自动返回。

function Person(name) {
  this.name = name;
}

const alice = new Person('Alice');
console.log(alice.name); // 输出 'Alice'
3. this 绑定的优先级

当多个规则同时出现时,this 的绑定优先级如下:

  1. new 绑定:如果使用了 new 关键字,this 会被绑定到新创建的对象。
  2. 显式绑定callapplybind 的显示绑定优先级高于隐式绑定和默认绑定。
  3. 隐式绑定:如果函数作为对象的方法调用,this 会绑定到该对象。箭头函数除外
  4. 默认绑定:如果没有特殊的绑定规则,this 会绑定到全局对象(非严格模式)或 undefined(严格模式)。

例子:

function foo() {
  console.log(this.name);
}

const obj1 = { name: 'obj1', foo };
const obj2 = { name: 'obj2' };

foo.call(obj2); // 显示绑定到 obj2,输出 'obj2'
obj1.foo(); // 隐式绑定到 obj1,输出 'obj1'
4. 绑定例外
4.1 被忽略的 this

如果通过 nullundefined 显式绑定 this,在调用时会忽略这种绑定,this 将会回退到默认绑定。

function foo() {
  console.log(this);
}

foo.call(null); // 在非严格模式下 this 会绑定到全局对象,严格模式下 this 是 undefined
4.2 间接引用

当将对象的方法赋值给另一个变量时,this 的绑定会丢失,回退到默认绑定。

const obj = {
  name: 'Alice',
  greet() {
    console.log(this.name);
  }
};

const greetFunc = obj.greet;
greetFunc(); // this 绑定丢失,回退到默认绑定 (全局对象/undefined)
4.3 软绑定

通过自定义函数,可以创建一个软绑定 this 的方案。如果 thisnullundefined,则 this 会被绑定到指定的默认对象。

if (!Function.prototype.softBind) {
  Function.prototype.softBind = function(obj) {
    const fn = this;
    return function() {
      return fn.apply(
        (!this || this === global) ? obj : this, arguments
      );
    };
  };
}

function foo() {
  console.log(this.name);
}

const person = { name: 'Alice' };
const softBoundFoo = foo.softBind(person);
softBoundFoo(); // 输出 'Alice'
5. this 词法

箭头函数没有自己的 this 绑定。箭头函数中的 this 是从定义它的上下文继承而来的,而不是调用时确定的。

const obj = {
  name: 'Alice',
  arrowFunc: () => {
    console.log(this.name); // 由定义它的上下文继承而来的,所以箭头函数中的 this 绑定到外部作用域,也就是全局window,obj此时还没有形成自己的上下文,因为obj的定义还没结束
  },
  normalFunc() {
    console.log(this.name); // 普通函数的 this 绑定到 obj
  }
};

obj.arrowFunc(); // 输出 undefined(取决于外部作用域的 this)
obj.normalFunc(); // 输出 'Alice'
6. 小结
  • this 的值取决于函数的调用位置。
  • 绑定规则分为:默认绑定、隐式绑定、显示绑定和 new 绑定。
  • 不同绑定规则有优先级,其中 new 绑定优先于显式绑定,显式绑定优先于隐式绑定。
  • 例外情况包括:被忽略的 this、间接引用和软绑定。
  • 箭头函数的 this 由外部词法作用域决定,不依赖调用时的上下文。

原文地址:https://blog.csdn.net/2301_79858914/article/details/142448669

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!