2015-05-19 30 views
5

我發現這個示例代碼:「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(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); 

我期望的「全名」屬性現在是一個字符串,而不是一個功能。但現在它提醒「undefined undefined」。任何人都可以解釋爲什麼我的版本不起作用?

+5

查看此答案,瞭解「this」的工作原理的完整說明:http://stackoverflow.com/questions/13441307/how-does-the-this-keyword-in-javascript-act-within-an-object -literal/13441628#13441628 – slebetman

回答

6

在JavaScript中,this通常是函數調用中的.之前的任何值。所以你說dude.fullName()這個事實是thisfullName()被設置爲dude 的原因。

在你的問題的第二個版本中,你不會以同樣的方式調用它。你打電話給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)做你期望的代碼的第二個版本和y您也可以在任何時候致電personFullName.apply(dude),並返回"Michael Jackson"

1

this是您的personFullName函數中的窗口,因爲它沒有在正確的上下文中調用。您可以使用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); 
1

一個更好的選擇來解決,這將是:

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

中,你在你的第二示例訪問this上下文中,引用window對象。 window沒有fullName屬性設置爲它。 如果您將添加到這兩個函數中,您會明白我的意思。