返回

ES5中令我头晕的this

前端

this是一个非常容易混淆的概念,尤其是在ES5中。之所以会这样,是因为this的指向规则既复杂又微妙。在本文中,我将详细介绍ES5中this的指向规则,并提供一些示例来说明这些规则是如何工作的。我还会分享一些实践技巧,帮助你更好地理解和使用this。

this的指向规则

在ES5中,this的指向规则主要有以下几条:

  • 当一个函数作为对象的方法被调用时,this指向该对象。
  • 当一个函数作为构造函数被调用时,this指向新创建的对象。
  • 当一个函数作为普通函数被调用时,this指向global对象(在浏览器中是window对象)。
  • 当一个函数使用call()、apply()或bind()方法被调用时,this指向第一个参数。

this的指向示例

为了更好地理解this的指向规则,我们来看一些示例。

// 示例1:作为对象方法被调用的函数

var person = {
  name: "John Doe",
  greet: function() {
    console.log("Hello, my name is " + this.name);
  }
};

person.greet(); // 输出:Hello, my name is John Doe

在这个示例中,greet()函数作为person对象的方法被调用,所以this指向person对象。因此,console.log()语句输出"Hello, my name is John Doe"。

// 示例2:作为构造函数被调用的函数

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

var john = new Person("John Doe");

console.log(john.name); // 输出:John Doe

在这个示例中,Person()函数作为构造函数被调用,所以this指向新创建的对象john。因此,console.log()语句输出"John Doe"。

// 示例3:作为普通函数被调用的函数

function greet() {
  console.log("Hello, my name is " + this.name);
}

greet(); // 输出:Hello, my name is undefined

在这个示例中,greet()函数作为普通函数被调用,所以this指向global对象(在浏览器中是window对象)。由于window对象没有name属性,所以console.log()语句输出"Hello, my name is undefined"。

// 示例4:使用call()方法被调用的函数

var person = {
  name: "John Doe"
};

var greet = function() {
  console.log("Hello, my name is " + this.name);
};

greet.call(person); // 输出:Hello, my name is John Doe

在这个示例中,greet()函数使用call()方法被调用,所以this指向第一个参数person。因此,console.log()语句输出"Hello, my name is John Doe"。

// 示例5:使用apply()方法被调用的函数

var person = {
  name: "John Doe"
};

var greet = function() {
  console.log("Hello, my name is " + this.name);
};

greet.apply(person); // 输出:Hello, my name is John Doe

在这个示例中,greet()函数使用apply()方法被调用,所以this指向第一个参数person。因此,console.log()语句输出"Hello, my name is John Doe"。

// 示例6:使用bind()方法被调用的函数

var person = {
  name: "John Doe"
};

var greet = function() {
  console.log("Hello, my name is " + this.name);
};

var boundGreet = greet.bind(person);

boundGreet(); // 输出:Hello, my name is John Doe

在这个示例中,greet()函数使用bind()方法被调用,所以this指向第一个参数person。因此,console.log()语句输出"Hello, my name is John Doe"。

实践技巧

以下是一些实践技巧,可以帮助你更好地理解和使用this:

  • 始终记住,this的指向是动态的,它可以根据函数的调用方式而改变。
  • 在调试this问题时,可以使用console.log()语句来输出this的值。
  • 如果你想明确指定this的指向,可以使用call()、apply()或bind()方法。
  • 如果你正在编写一个库或框架,你应该使用箭头函数来定义方法,因为箭头函数总是绑定到其父作用域的this。

总结

this是一个非常容易混淆的概念,尤其是在ES5中。然而,通过理解this的指向规则和一些实践技巧,你可以更好地理解和使用this。