2011-08-18 44 views
4
function getCtr(){ 
    var i = 0; 
    return function(){ 
    console.log(++i); 
    } 
} 
var ctr = getCtr(); 
ctr(); 
ctr(); 

我一直在使用Javascript來自過去五年,但這個問題讓我在上次採訪中變得愚蠢。我嘗試了所有知識,但無法弄清楚。這個javascript的輸出和原因

你能幫我解釋一下它的輸出和原因嗎,這樣我可以更好地裝備未來的採訪,如果我有一個。

+2

......它只是打印出 '1' 和 '2',是否正確? –

+1

那麼你期望的輸出是什麼? –

+0

http://jsfiddle.net/TyHp3/ –

回答

3
var ctr = getCtr(); 

這要求getCtr(),初始化i到0,並存儲到函數

function() { 
    console.log(++i) 
} 
在CTR

的參考。由於該函數是在getCtr()的範圍內創建的,因此變量i仍然可以在存儲在ctr中的函數範圍內訪問。

第一次調用

ctr() 

執行console.log(++i)具有前增量上我,所以它打印出1。第二次調用執行相同的代碼,使用相同的預增量,並打印出2

免責聲明:不是一個JavaScript開發人員。如果我犯了一個錯誤或者使用了一些不理想的措辭,請原諒我。

0

run this: var m = 0; var d = 0;

alert(m ++ +「:」+ ++ d);

,你會得到「0:1」

如果是我問在接受採訪時,當++的區別就是我會是什麼後:) http://jsfiddle.net/MarkSchultheiss/S5nJk/

0

Closures

該函數中的return語句保存爲i。所以當var i = 0;只叫var ctr = getCtr();。然後CTR變成返回的函數:

function() { 
     console.log(++i) 
    } 

和可變CTR在外部函數,getCtr()的範圍具有i和返回功能是在getCtr()範圍爲好。

0

好吧,getCtr是一個返回其他函數的函數。 它還包含一個名爲「i」的var,它被設置爲0. 「i」在返回的函數範圍內也可用。 在將日誌記錄到控制檯之前預先增加「i」會導致每次調用存儲在「ctr」中的返回函數時,它都會增加1。

0

執行時,函數getCtr返回一個內部匿名函數。 此函數現在被變量ctr引用 由於匿名函數是在getCtr內部創建的,因此它將訪問包含變量'i'的getCtr私有範圍對象。這被稱爲封閉

var ctr = getCtr() 

每次執行匿名函數時,它都會預先遞增i,然後寫入控制檯。

ctr() 
1

所以你的代碼貼出輸出12。然而,代碼:只有11

function getCtr(){ 
    var i = 0; 
    return function(){ 
    console.log(++i); 
    } 
} 
getCtr()(); 
getCtr()(); 

輸出!

區別在於,如果使用var ctr = getCtr();保存對getCtr()的引用,則可以創建稱爲閉包的對象。

因此撥打getCtr()()ctr()的區別在於ctr已在我的範圍內定義,並且該範圍由於var ctr = getCtr();而得到保存。由於參考被保存,ctr內部的功能可以始終作用於相同的變量。

0

讓我們打破它使用方面你可能知道,從傳統的基於繼承OOP語言:

// In javascript functions are first-class objects 
// This function is being used like a class would be in Java 
function getCtr(){ 
    // You can think of this as a private variable of the getCtr "class" 
    var i = 0; 
    // Because it is returned, this is effectively a public method of getCtr 
    return function(){ 
     // Which increments i and then prints it. 
     console.log(++i); 
    } 
} 

// This makes the variable ctrl an instance of getCtr. 
var ctr = getCtr(); 
// This calls ctr's only public method. 
ctr(); 
ctr(); 

所以輸出將是「1,2」。

這個問題的意思是測試你是否理解了Javascript的prototypal inheritance,能力有anonymous functionsclosures

澄清的那個版本可能會做同樣的事情將是:

var myProtoype = function() { 
    var privateVariable = 0; 
    var privateMethod = function() { 
     privateVariable++; 
     console.log(privateVariable); 
    } 
    return { 
     publicMethod: privateMethod 
    }; 
} 

var myInstance = new myPrototype(); 
myInstance.publicMethod(); 
myInstance.publicMethod(); 
0

這個函數是一個Javascript模塊。你可以在Javascript上閱讀它:Good Parts,這是一本很棒的書,我強烈推薦。一個模塊使用Javascript關閉來創建私有變量,如果分配給一個var,var每次調用時都會保留它的變量,而不是重新定義變量。

模塊的工作原理如下

function moduleName(privateVar1){ 
    var privateVar1; 
    var privateVar2; 

    return { 
     exposedFunction1: function (var1) { 
      // Do stuff... using private vars 
      return something; 
     }, 
     exposedFunction2: function (var1, var2) { 
      // Do stuff... 
      return something; 
     } 
    } 
} 

var moduleInstance = moduleName(privateVar1); 
moduleInstance.exposedFunction(var1); 
相關問題