javascript中的“this”的指向

引言:

在 JavaScript 编程中,存在一个让许多初学者感到困惑的问题:this 的指向。这个看似简单的关键字,在不同的上下文中却可能指向不同的对象,让人摸不着头脑。本文将带你深入探索 JavaScript 中 this 的指向规则,解开这个神秘的面纱。

一、默认绑定规则:

当函数独立调用时,没有任何前缀或绑定操作,this 默认指向全局对象。让我们看一个例子:

function sayHello() {
  console.log("Hello, " + this.name);
}

var name = "binjie";
sayHello(); // 输出:Hello, binjie

二、隐式绑定规则:

当函数作为对象的方法调用时,this 指向调用该方法的对象。下面是一个例子:

var obj = {
  name: "binjie",
  sayHello: function() {
    console.log("Hello, " + this.name);
  }
};

obj.sayHello(); // 输出:Hello, binjie

三、显式绑定规则:

当需要显式地绑定函数内部的 this 值时,JavaScript 提供了三个方法:callapply 和 bind。它们可以修改函数执行时的 this 指向,并且可以传递参数给被调用的函数。

  1. call 方法:

call 方法可以在函数执行时指定函数内部的 this 值,并且可以传递多个参数。

语法:

function.call(thisArg, arg1, arg2, ...)
  • thisArg:指定的 this 值,即函数执行时的上下文对象。
  • arg1, arg2, ...:要传递给函数的参数列表。

示例:

function sayHello(message) {
  console.log(message + ", " + this.name);
}

var obj = {
  name: "binjie"
};

sayHello.call(obj, "Hello"); // 输出:Hello, binjie

在上面的例子中,call 方法将 sayHello 函数内部的 this 绑定到了 obj 对象,并传递了一个字符串参数 "Hello"

  1. apply 方法:

apply 方法与 call 方法类似,也可以在函数执行时指定函数内部的 this 值,并且可以传递一个参数数组。

语法:

function.apply(thisArg, argsArray)
  • thisArg:指定的 this 值,即函数执行时的上下文对象。
  • argsArray:要传递给函数的参数数组。

示例:

function sayHello(message) {
  console.log(message + ", " + this.name);
}

var obj = {
  name: "binjie"
};

sayHello.apply(obj, ["Hello"]); // 输出:Hello, binjie

在上面的例子中,apply 方法将 sayHello 函数内部的 this 绑定到了 obj 对象,并传递了一个包含单个元素 "Hello" 的参数数组。

  1. bind 方法:

bind 方法会创建一个新函数,并将原函数内部的 this 绑定到指定的对象。不同于 call 和 applybind 并不会立即执行函数,而是返回一个绑定了 this 的新函数。

语法:

function.bind(thisArg, arg1, arg2, ...)
  • thisArg:指定的 this 值,即新函数执行时的上下文对象。
  • arg1, arg2, ...:要传递给新函数的参数列表。

示例:

function sayHello(message) {
  console.log(message + ", " + this.name);
}

var obj = {
  name: "binjie"
};

var boundFunc = sayHello.bind(obj, "Hello"); // 创建一个新函数,绑定了 this 和参数
boundFunc(); // 输出:Hello, binjie

在上面的例子中,bind 方法创建了一个新函数 boundFunc,并将 sayHello 函数内部的 this 绑定到了 obj 对象,并传递了一个字符串参数 "Hello"。通过调用 boundFunc(),就可以执行绑定了 this 的新函数。

总结:

  • call 和 apply 可以立即执行函数,并显式地绑定函数内部的 this 值。
  • bind 创建一个新函数,绑定了 this 并可选地绑定参数。返回的新函数可以稍后调用。

这三个方法在需要控制函数内部的 this 值时非常有用,可以灵活地修改函数的执行上下文。

四、构造函数规则:

在 JavaScript 中,每个函数都有一个 this 关键字,用于引用当前执行代码的对象。在构造函数中,当使用 new 操作符创建新对象实例时,构造函数内部的 this 关键字会被绑定到新创建的对象上。

具体来说,构造函数规则如下:

  1. 使用 new 关键字调用构造函数:使用 new 关键字后面跟随构造函数的名称,可以创建一个新的对象实例。

  2. 创建一个空对象:在调用构造函数时,会创建一个空对象作为新的对象实例。

  3. 将构造函数内部的 this 绑定到新创建的对象:在构造函数执行过程中,构造函数内部的 this 关键字会被绑定到新创建的对象上,以便在构造函数内部可以访问和修改该对象的属性和方法。

  4. 属性和方法的添加:在构造函数内部,可以通过使用 this 关键字来为新对象添加属性和方法。

  5. 返回新创建的对象实例:构造函数执行完毕后,会隐式地返回新创建的对象实例。如果构造函数内部没有显式返回其他对象,则返回的就是新创建的对象实例。

下面是 new 操作符的执行过程:

  1. 创建一个新的空对象;

  2. 将新创建的空对象的原型指向构造函数的 prototype 属性;

  3. 使用新对象调用构造函数,将 this 关键字绑定到新创建的对象上;

  4. 在构造函数内部,可以使用 this 来添加属性和方法到新对象上;

  5. 隐式返回新对象实例。如果构造函数内部没有显式返回其他对象,则 JavaScript 引擎隐式地返回新创建的对象实例。

下面是一个示例代码:

// 定义一个构造函数
function Person(name, age) {
  // 构造函数内部的 this 绑定到新创建的对象上
  this.name = name;
  this.age = age;
  
  // 添加方法
  this.sayHello = function() {
    console.log("Hello, my name is " + this.name);
  };
}

// 使用 new 关键字调用构造函数创建对象实例
var person1 = new Person("Alice", 25);
var person2 = new Person("Bob", 30);

// 访问对象的属性和方法
console.log(person1.name); // 输出:Alice
console.log(person2.age); // 输出:30
person1.sayHello(); // 输出:Hello, my name is Alice
person2.sayHello(); // 输出:Hello, my name is Bob

在上述示例中,我们定义了一个 Person 构造函数,并使用 new 操作符创建了两个新的对象实例。在构造函数内部,我们使用 this 关键字将属性和方法绑定到新创建的对象上,以便在对象实例中可以访问和修改它们。随后,JavaScript 引擎将隐式地返回新创建的对象实例,赋值给变量 person1 和 person2

五、箭头函数规则:

箭头函数没有自己的 this 值,它会捕获上层作用域中的 this 值,并将其作为自己的 this 值。下面是一个例子:

var obj = {
  name: "binjie",
  sayHello: function() {
    var arrowFunc = () => {
      console.log("Hello, " + this.name);
    };
    arrowFunc();
  }
};

obj.sayHello(); // 输出:Hello, binjie

示例中,obj 对象包含一个名为 sayHello 的方法。在该方法内部,我们定义了一个箭头函数 arrowFunc,并在其中打印了 this.name 的值。由于箭头函数没有自己的 this 值,它会捕获上层作用域中的 this 值,并将其作为自己的 this 值。在这个例子中,箭头函数 arrowFunc 定义在 sayHello 方法中,因此它的上层作用域是 obj 对象。因此,arrowFunc 内部的 this 值指向 obj 对象,从而能够访问到对象的 name 属性。最终输出的结果为 "Hello, binjie",也证明了箭头函数在这个例子中成功地捕获了 obj 对象的 this 值。

结论:

综上所述,JavaScript 中的 this 可以说是一个充满挑战又富有奇妙之处的概念。通过理解默认绑定、隐式绑定、显式绑定、构造函数和箭头函数等规则,我们可以更好地掌握 this 的用法,并在编写 JavaScript 代码时避免出现混乱和错误。

希望本文能够帮助你解开 this 的神秘面纱,并在日常的 JavaScript 编程中更加游刃有余!

  • 21
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值