Javascript “怎么做?”;这";在构造函数中分配的函数中工作?

Javascript “怎么做?”;这";在构造函数中分配的函数中工作?,javascript,function,constructor,this,Javascript,Function,Constructor,This,我发现了以下示例代码: 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

我发现了以下示例代码:

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());
提醒“迈克尔·杰克逊”。我将其更改为从构造函数调用
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中,
这通常是函数调用中
之前的内容。因此,您所说的
dude.fullName()
是导致
fullName()
中的
this
设置为
dude
1的原因

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

要解决此问题,可以将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();
}
未捕获类型错误:this.personFullName不是函数

这也不会:

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());
未捕获类型错误:dude.personFullName不是函数


在任何情况下,您都可以使用helper方法绕过此限制:
this.fullName=personFullName.apply(this)
执行您希望代码第二个版本执行的操作,您也可以随时调用
personFullName.apply(dude)
,并获得“Michael Jackson”
返回。

这是
personFullName
函数中的窗口,因为它没有在正确的上下文中调用。您可以使用来使用正确的上下文调用它,而无需修改
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;
}

在第二个示例中,您访问
的上下文引用了
窗口
对象<代码>窗口
未设置
全名
属性。
如果您添加
警报(此)
对于这两个函数,您都会明白我的意思。

请参阅此答案,以了解
如何工作的完整说明: