“这是怎么回事?”在构造函数中赋值的函数中工作

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

本文关键字:赋值 函数 工作 构造函数 怎么回事      更新时间:2023-09-26

我找到了这个示例代码:

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"属性现在是一个字符串而不是一个函数。但现在它警告"未定义未定义"。谁能解释一下为什么我的版本不行?

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

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

要解决这个问题,您可以将您的person作为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 helper方法来绕过此限制:this.fullName = personFullName.apply(this)执行您期望的第二版本代码所做的工作,并且您还可以在任何时候调用personFullName.apply(dude)并获得"Michael Jackson"

thispersonFullName函数中的窗口,因为它没有在正确的上下文中调用。您可以使用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);添加到这两个函数中,您就会明白我的意思。