【问题标题】:JS - Confusion on function that rewrite tyselfJS - 对重写 tyself 的功能感到困惑
【发布时间】:2016-04-25 00:36:17
【问题描述】:

致所有 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 is not a function,而不是工作。

这里有什么错误??

谢谢

【问题讨论】:

    标签: javascript jquery


    【解决方案1】:

    第一行:

    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
    

    【讨论】:

    • 所以正确的应该是return function() {alert('B')} 而不是那个。所以书上的错误??
    • 是的,返回这样的函数将适用于a = a()。我会将其添加到我的答案中。
    • 您还应该阅读有关函数提升的内容。这发生在这里,应该注意
    【解决方案2】:

    当你第一次打电话时

    a = a(); // First Call
    

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

    将第一行更改为 a() 即可解决此问题。

    【讨论】:

      【解决方案3】:

      这个例子展示了变量和函数的命名及其作用域在 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 'outside' 决定(可以这么说) - 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(它本身)重置为新函数,然后在再次调用时触发console.log(B)

      可以从中挤出更多细节,以及实现相同结果的更好方法,但对控制台的调用是了解正在发生的事情的重要线索。不要将示例视为可用的模式 - 将其视为暗示 JavaScript 引擎如何执行其工作的东西。

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

      【讨论】:

      • 感谢您的帮助。顺便提一下你提到的可用模式,你有什么好书推荐来学习最新的javascript应用模式吗??
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 2013-08-21
      • 2022-01-11
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多