解密JavaScript中的this关键字(规则篇)

80 阅读3分钟

引言

JavaScript中的this关键字在函数调用时被绑定到一个对象上,它的指向取决于调用函数的方式和位置。理解this的绑定规则对于正确使用和设计JavaScript代码至关重要。本文将详细介绍JavaScript中的this绑定规则,包括默认绑定、隐式绑定、显示绑定和new绑定。

1. 默认绑定

默认绑定是当函数被独立调用时应用的规则。在这种情况下,this指向全局对象(在浏览器环境中为window对象)。

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

foo();

另一个例子是函数调用链,其中多个函数相互调用,但没有绑定到特定对象上。

function test1() {
  console.log(this); // window
  test2();
}

function test2() {
  console.log(this); // window
  test3()
}

function test3() {
  console.log(this); // window
}

test1();

即使将函数作为参数传递给另一个函数,也会应用默认绑定。

function foo(func) {
  func()
}

function bar() {
  console.log(this); // window
}

foo(bar);

2. 隐式绑定

隐式绑定是通过某个对象进行函数调用时应用的规则。调用位置中,函数通过对象发起调用,从而将this隐式地绑定到该对象上。

function foo() {
  console.log(this); // obj对象
}

var obj = {
  name: "why",
  foo: foo
}

obj.foo();

隐式绑定的例子还可以是通过一个对象间接引用另一个对象来调用函数。

function foo() {
  console.log(this); // obj对象
}

var obj1 = {
  name: "obj1",
  foo: foo
}

var obj2 = {
  name: "obj2",
  obj1: obj1
}

obj2.obj1.foo();

然而,当隐式绑定丢失时,this会回退到默认绑定。

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

var obj1 = {
  name: "obj1",
  foo: foo
}

var bar = obj1.foo;
bar(); // window

3. 显示绑定

显示绑定是通过callapplybind方法明确地指定this的绑定对象。

通过callapply方法绑定this对象:

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

foo.call(window); // window
foo.call({name: "why"}); // {name: "why"}
foo.call(123); // Number对象, 存放时123

可以自己编写一个辅助函数实现显示绑定:

function foo() {
  console

.log(this);
}

function bind(fn, obj) {
  return function() {
    fn.call(obj);
  }
}

var obj = {
  name: "obj"
}

var bar = bind(foo, obj);
bar(); // obj

bind方法返回一个新函数,将this绑定到指定对象。

4. new绑定

当使用new关键字调用构造函数时,会发生new绑定。在这种情况下,会创建一个新对象,同时将this绑定到该新对象上。

function Person(name) {
  this.name = name;
  console.log(this); // 新创建的对象
}

var person = new Person("why");

使用new关键字调用构造函数会依次执行以下步骤:

  1. 创建一个新对象。
  2. 将新对象的原型链连接到构造函数的原型上。
  3. 将构造函数的this绑定到新对象上。
  4. 执行构造函数内部的代码。
  5. 如果构造函数没有返回其他对象,那么会隐式返回新对象。

5. 优先级规则

在以上四种绑定规则中,new绑定的优先级最高,其次是显示绑定,然后是隐式绑定,而默认绑定的优先级最低。

需要注意的是,当多种规则同时出现时,优先级高的规则会覆盖优先级低的规则。

结论

本文详细介绍了JavaScript中的this绑定规则。了解这些规则对于正确理解代码中的this指向非常重要。通过默认绑定、隐式绑定、显示绑定和new绑定四种规则,我们可以灵活地控制this的指向,以适应不同的使用场景。同时,我们还讨论了这些规则的优先级,以帮助我们更好地理解this的工作方式。对于开发人员来说,熟练掌握this的绑定规则是编写高质量JavaScript代码的关键。

希望本文对你有所帮助。如果你有任何问题或需要进一步解释,请随时提问。谢谢!