2016-04-25 62 views
1

對於所有的JS專家, 我仍然試圖學習使用來自書籍的JS Stoyan Stefanov(面向對象的JS)。JS - 重寫tyself的功能混淆

停頓在頁83,在下面的代碼必須工作,

a = a(); // First Call 
 
function a() { 
 
alert('A'); 
 
a = function() { // I get this. Redefining functions. 
 
    alert('B'); 
 
}; 
 
} 
 
a(); // Second Call

書中建議,如果我們呼叫/調用的第二次它會實際上發生警報A後警報B

然而,不是工作它給我們類型錯誤:一個是不是一個函數成功警報A.

請告訴我這裏的錯誤後?

謝謝

回答

2

第一行:

a = a(); 

調用功能,並指定其返回值a。但是函數的返回值是undefined - 任何沒有明確返回值的函數將會隱含返回undefined(除非用new調用,但您可以在此忽略)。那麼在最後一行當你說a()你基本上是在說undefined()。當然undefined不是一個函數。

本書中的代碼是否真的說a = a();?將其更改爲a(),它將按預期工作。

或者你可以改變功能,在第一次調用返回新的功能,而不是直接覆蓋a

a = a(); // First Call 
function a() { 
alert('A'); 
// following line changed to return the new function instead 
// of assigning it to a immediately 
return function() { 
    alert('B'); 
}; 
} 
a(); // Second Call 
+0

所以正確的做法應該是'恢復功能(){警報( 'B')}',而不是說。所以書中的錯誤? – xcode

+0

是的,返回像'a = a()'那樣的函數。我會將其添加到我的答案中。 – nnnnnn

+0

謝謝。非常清楚和有用的答案 – xcode

0

當你

a = a(); // First Call 

分配函數結果第一個呼叫你的變量a。然而你的a()不會返回任何東西。因此,第二次嘗試時,a是undefined

將第一行改爲a()修復它。

0

這個例子顯示了變量和函數的命名及其範圍在JavaScript中的重要性。考慮下面的代碼...

a = a(); 
console.log('typeof global variable a :',(typeof a)); 
function a() { 
    console.log('A'); 
    a = function() { 
     console.log('B'); 
    }; 
    console.log('typeof global function a() inner function a() :',(typeof a)); 
} 
console.log('typeof global function a() :',(typeof a)); 
a(); 

//=> ! TypeError: a is not a function 
//=> A 
//=> typeof global function a() inner function a() : function 
//=> typeof global variable a : undefined 
//=> typeof global function a() : undefined 

那麼這是怎麼回事?

function a()的內部變量a返回它的類型:function

全局變量a設置爲function a()的返回值 - 但這樣它會自動成爲undefined

功能不返回任何東西全球function a()的類型仍然由值a'外部'自己(可以這麼說) - undefined

N注意console.log()的呼叫到達的順序?

不僅內部a沒有設置爲var,而是自動將其置於全局範圍內,但是a = a()意味着它不再是一個函數!

它是a = a()這導致a is not a function TypeError。

在另一方面,當看我刪除a =但留下的一切,因爲它是...

a(); 
console.log('typeof global variable a :',(typeof a)); 
function a() { 
    console.log('A'); 
    a = function() { 
     console.log('B'); 
    }; 
    console.log('typeof global function a() inner function a() :',(typeof a)); 
} 
console.log('typeof global function a() :',(typeof a)); 
a(); 

//=> A 
//=> typeof global function a() inner function a() : function 
//=> typeof global function a() : function 
//=> typeof global variable a : function 
//=> B 

如何看順序改變了會發生什麼?

現在我們不能將'全局變量a'(像以前一樣)當作變量來考慮 - a只是一個指向函數的標記。

function a()被調用時,將觸發console.log(),復位令牌a(它本身)的新功能,並且然後將觸發console.log()時再次調用。

有更多的細節可以從中擠出來,以及達到相同結果的更好方法,但調用控制檯對於發生的事情是一個很大的線索。不要把這個例子看作是一個可用的模式 - 把它想象成一個暗示JavaScript引擎如何執行它的功能的東西。

您可能會發現這篇文章從JavaScriptIsSexy.com有用:JavaScript Variable Scope and Hoisting Explained

+0

感謝您的幫助。順便提一下關於可用模式,你推薦學習JavaScript應用最新模式的好書嗎? – xcode