2016-01-11 59 views
4

我對理解方法的原理有所懷疑。
我理解的功能,我知道JavaScript - 瞭解方法

function hello() { 
    alert('Hello World'); 
} 

相同

var hello = function() { 
    alert('Hello World'); 
} 

現在,什麼是我的問題。
這是我的一個方法的對象。我不明白爲什麼 括號不需要在yarsLeft裏面function people()
我在尋找合乎邏輯的解釋。

function people(name, age) { 
    this.name = name; 
    this.age = age; 
    this.yearsUntilRetire = yearsLeft; // this is confised for me 
} 

function yearsLeft() { 
    var numYears = 65 - this.age; 
    return numYears; 
} 

創建對象

var test = new people('Superman', 50); 
test.yearsUntilRetire(); // I understand this code and calling a method in that way 

爲什麼我不能寫this.yearsUntilRetire() = yearsLeftthis.yearsUntilRetire = yearsLeft();

+1

這是一個函數引用。函數可以像JS中的任何其他類型一樣引用和傳遞。 – Teemu

+1

'()'將調用(調用)該函數。您正在將函數表達式設置爲'this.yearsUntilRetire'。一旦你調用'this.yearsUntilRetire()',函數表達式就會被執行。 – Rayon

回答

7

當您使用函數的名稱不使用括號(())要在基準設置爲功能本身

當您使用括號同樣的功能你是執行功能

因此這條線

this.yearsUntilRetire = yearsLeft; 

是設置yearsUntilRetire指向功能。此後,你可以這樣做:

this.yearsUntilRetire(); // execute the yearsLeft function. 

爲什麼我不能寫this.yearsUntilRetire()= yearsLeft或this.yearsUntilRetire = yearsLeft();

在第一種情況下,您不能將調用函數的結果設置爲不同的結果 - 這是語法錯誤。

在第二種情況下,可以 - 它把變量yearsUntilRetire到調用函數yearsLeft

1

1)function hello() {alert('Hello World');} 的結果不相同var hello = function() {alert('Hello World');}

第一個是函數聲明。第二個是分配給一個名爲hello的變量的函數表達式。但是當然在使用這兩個函數的時候,你可以把它看作相同,並且兩者的行爲都是相同的。

2)函數總是被稱爲函數名稱,後面跟括號,例如:yearsLeft()。這就是調用函數的唯一方法。

函數是JS中的First Class對象。它可以被聲明,表達,分配,傳遞給另一個函數並從一個函數返回。

所以在你的情況下,你的意圖是將全局函數yearsLeft分配給對象屬性yearsUntilRetire。你完成任何其他任務完成的方式 - 請記住「函數是頭等對象

1

這裏有幾個工作示例來說明您的問題的答案。 請參閱內嵌評論以獲取解釋。

console.assert(typeof helloWorldAsVar === 'function', 'helloWorldAsVar is defined'); 
 
console.log(helloWorldAsVar); 
 
console.assert(typeof helloWorld === 'function', 'helloWorld is defined'); 
 
// creating a function like helloWorld means it will be hoisted to the top of the file as js does two passes 
 
// when compiling the script. one to declare all the functions and initialize all the variables as undefined. 
 
// and another to run through the code. 
 
console.log(helloWorld); 
 

 

 
var helloWorldAsVar = function() { 
 
    return 'this will not get hoisted, and the function name is anonymous'; 
 
} 
 
// helloWorldAsVar is only available after it is declared. 
 
console.assert(typeof helloWorldAsVar === 'function', 'helloWorldAsVar is defined'); 
 
console.log(helloWorldAsVar); 
 

 
function helloWorld() { 
 
    return 'this will get hoisted to the top of the function, and it will keep its name'; 
 
}
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"> 
 
</script>

// this is a constructor function, it is essentially a typed object that can 
 
// have it's own methods similar to an oop class in other languages like php or java 
 
// the convention is to name a constructor with the first letter capitalized and it should be singular 
 
function Person(name, age) { 
 
    // here you are assigning properties to your People object 
 
    this.name = name; 
 
    this.age = age; 
 
    // you are passing a reference to the yearsLeft function 
 
    // this.yearsUntilRetire = yearsLeft; 
 
} 
 

 
// a more standard way to add the yearsLeft function is to 
 
// use the People.prototype object which get's methods delegated to it eg. 
 
Person.prototype.yearsUntilRetire = yearsLeft; 
 

 
function yearsLeft() { 
 
    var numYears = 65 - this.age; 
 
    return numYears; 
 
} 
 

 
// Create objects 
 
var superman = new Person('Clark', 50), 
 
    batman = new Person('Bruice', 40); 
 

 
console.log(superman, 'yearsUntilRetire', superman.yearsUntilRetire()); 
 
console.log(batman, 'yearsUntilRetire', batman.yearsUntilRetire()); 
 

 
// Why I can 't write this.yearsUntilRetire() = yearsLeft or this.yearsUntilRetire = yearsLeft(); 
 
console.assert(this === window, 'this in the global context refers to the window object'); 
 
console.assert(superman instanceof Person, 'superman is a Person'); 
 
console.assert(batman instanceof Person, 'batman is a Person');
<script src="http://codepen.io/synthet1c/pen/WrQapG.js"></script>