2016-04-25 63 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