2013-05-17 62 views
2

有人可以解釋爲什麼我會在下列每種情況下得到結果嗎?我希望理解爲什麼結果是關於JavaScript如何在範圍內工作的結果,如果這是問題所在。在第一個例子中,我的代碼正常工作。解釋這個未捕獲的類型錯誤:對象[對象對象]的屬性'x'不是函數

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

}; 

var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 


var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

如果我移動addSalaryFunctionEmployees功能,以下this.addSalary我得到的遺漏的類型錯誤。

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

    var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 
}; 

var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

但是,如果我移動addSalaryFunction上述this.addSalary如果工作正常試。儘管我的IDE告訴我,我的本地變量addSalaryFunction是多餘的。

var Employees = function(name, salary) { 
    this.name = name; 
    this.salary = salary; 

    var addSalaryFunction = function(addition) { 
     this.salary = this.salary + addition; 
    }; 

    this.addSalary = addSalaryFunction; 

    this.getSalary = function() { 
     return this.salary; 
    }; 

}; 


var ceo = new Employees("Chris", 400000); 
ceo.addSalary(20000); 
document.write(ceo.getSalary()); 

回答

7

這是因爲您正在嘗試在創建函數之前分配函數。

this.addSalary = addSalaryFunction; // there's no function yet 

//... 

var addSalaryFunction = function(addition) { // now there is, but too late 
    this.salary = this.salary + addition; 
}; 

當你移動的變量賦值的​​以上,現在你想引用它之前創造的功能。

var addSalaryFunction = function(addition) { // here's the function 
    this.salary = this.salary + addition; 
}; 
this.addSalary = addSalaryFunction; // now we can assign it 

如果你曾經使用函數聲明的語法來代替,第一個版本會的工作,因爲函數聲明「懸掛」 (他們說)的變量範圍的頂部。

this.addSalary = addSalaryFunction; // This now works because of the magic below 

//... 

// This is magically hoisted to the top 
function addSalaryFunction(addition) { 
    this.salary = this.salary + addition; 
} 
+0

[很好的解釋](http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/) – RobH

+0

爲徹底性。 – rGil

+0

@chris_s:不客氣。最終,最乾淨的解決方案是使用*** rGil ***發佈的內容。但是,IMO更好的是通過將所有方法放在'Employees.prototype'上來使用原型繼承。然後它們在所有Employee對象之間共享,而不是爲每個對象重新創建。 – 2013-05-17 13:33:58

2

第二種方法不起作用,因爲addSalaryFunction在聲明之前被引用。

您可以消除一些代碼,只是聲明:

this.addSalary = function(addition) { 
    this.salary = this.salary + addition; 
} 
0

在一個更簡單的形式:

var foo = function() { 
    var x = y; 
    var y = 2; 
    return x; 
}; 

var bar = function() { 
    var y = 2; 
    var x = y; 
    return x; 
}; 

顯然,bar()將返回2. foo,然而,得到undefined在查找第一行的值爲y,所以返回undefined。雖然變量聲明被懸掛在其範圍的頂部,但變量初始值沒有。

相關問題