JS - 重写自己的功能混乱

时间:2016-04-25 00:36:17

标签: javascript jquery

致所有JS专家, 我仍在尝试使用 Stoyan Stefanov(面向对象的JS)中的书来学习JS。

卡在第83页上,以下代码必须正常工作,

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

该书建议,如果我们第二次调用/调用,警报A出现后,实际上会警告B

但是,在成功提醒A后,它不会给它们提供 TypeError:a不是函数

这里的错误是什么?

谢谢

3 个答案:

答案 0 :(得分:2)

第一行:

a = a();

调用该函数并将其返回值赋给a。但函数的返回值为undefined - 任何未显式返回return值的函数都将隐式返回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

答案 1 :(得分:0)

当你第一次打电话时

a = a(); // First Call

将函数结果赋给变量a。然而你的a()并没有返回任何东西。因此,在第二次尝试时,a为undefined

将第一行更改为a()只会修复它。

答案 2 :(得分: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

那是怎么回事?

a的内部变量function a()返回其类型:function

全局变量a设置为function a()的返回值 - 但该函数不返回任何内容,因此它自动变为undefined

全局function a()的类型仍然由其自身之外的值a确定(可以这么说) - undefined

请注意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 ),将令牌a(本身)重置为新函数,然后触发{{1}再次调用B console.log(

可以从中榨取更多细节,以及实现相同结果的更好方法,但是对控制台的调用是发生了什么的一个重要线索。不要将该示例视为可用模式 - 将其视为暗示JavaScript引擎如何执行其操作的内容。

您可能会发现JavaScriptIsSexy.com中的这篇文章很有用:JavaScript Variable Scope and Hoisting Explained