"this" 如何在构造函数中分配的函数中工作?

How does "this" work in functions that are assigned in the constructor?

我找到了这个示例代码:

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName;
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName());

哪个警报 "Michael Jackson"。我将其更改为从构造函数调用 personFullName 而不是分配函数对象:

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName();
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName);

我希望 "fullName" 属性 现在是字符串而不是函数。但现在它提醒 "undefined undefined"。谁能解释为什么我的版本不起作用?

在 JavaScript 中,this 通常是函数调用中 . 之前的任何内容。所以你说 dude.fullName() 是导致 fullName() 中的 this 被设置为 dude1 的原因。

在你问题的第二个版本中,你没有以相同的方式调用它。您在调用 personFullName() 之前没有任何内容(这是正确的,因为它不再附加到 Person 对象)。这意味着 this 最终默认为与 window 相同的值。由于 window 没有设置 firstlast 属性,因此 this.firstthis.lastundefined.

要解决此问题,您可以让您的人成为 personFullName() 函数的参数:

function personFullName(person) {
    return person.first + ' ' + person.last;
}

然后像这样称呼它

…
this.fullName = personFullName(this);

1: 请注意,该方法必须是对象上的 属性 才能使 this 绑定起作用。您不能只调用 object.someMethod() 并在 someMethod 中将 this 设置为 object。在您的代码中,以下内容不起作用:

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = this.personFullName();
}

Uncaught TypeError: this.personFullName is not a function

这也不会:

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
}

var dude = new Person("Michael", "Jackson");
alert(dude.personFullName());

Uncaught TypeError: dude.personFullName is not a function

您可以在任何情况下使用 apply 辅助方法绕过此限制:this.fullName = personFullName.apply(this) 执行您希望第二个版本的代码执行的操作,您也可以调用 personFullName.apply(dude) 在任何时候得到 "Michael Jackson" 回来。

thispersonFullName 函数中的 window,因为它没有在正确的上下文中调用。您可以使用 apply 在正确的上下文中调用它,而无需修改 personFullName 函数。

function personFullName() {
    return this.first + ' ' + this.last;
}

function Person(first, last) {
    this.first = first;
    this.last = last;
    this.fullName = personFullName.apply(this); // The magic
}

var dude = new Person("Michael", "Jackson");
alert(dude.fullName);

解决此问题的更好替代方法是:

Person.prototype.personFullName = function() {
    return this.first + ' ' + this.last;
}

您在第二个示例中访问 this 的上下文正在引用 window 对象。 window 没有 fullName 属性 设置。 如果您将 alert(this); 添加到两个函数,您就会明白我的意思。