代码之家  ›  专栏  ›  技术社区  ›  Hammerite

当我使用“传统的”C风格的函数声明时,JavaScript中发生了什么?

  •  9
  • Hammerite  · 技术社区  · 14 年前

    我知道有几种方法可以在JavaScript中定义函数。最常见的两种是:

    (1)  function add (a, b) {
             return a + b;
         }
    
    (2)  var add = function (a, b) {
             return a + b;
         }
    

    (2) 他在做什么。它正在创建一个函数并分配给 add (假设这是在全球范围内,所以 添加 是全局变量)的函数。但是如果我使用 (1) 相反呢?我已经知道,如果我使用 (1) add() 在代码中 添加() 定义了,但如果我使用 (2) 添加 在我开始提到

    (1) 只是一条捷径 (2) ,尽管它的行为恰好与其他C风格的语言类似,允许我们定义一个“低于”使用点的函数?或者它在内部是一种不同类型的功能?哪一个更符合JavaScript的“精神”(如果这个术语不太模糊的话)?你会把自己限制在一个或另一个,如果是,哪一个?

    2 回复  |  直到 14 年前
        1
  •  6
  •   Community CDub    8 年前

    看起来你已经意识到了 function declarations (1) 以及 function expressions add 包含函数值,如(2)所示:

    function hello () {
       alert('Hello World');
    }
    
    console.log(typeof hello);  // prints "function"
    
    setTimeout(hello, 1000);    // you can still pass functions around as arguments,
                                // even when using function declarations.
    

    另一点值得一提的是 (1) 不应用于有条件地定义函数(例如 if 语句),因为正如您所提到的,它们被JavaScript解释器自动移动到包含范围的顶部 2 . 这通常称为 hoisting .

    至于哪种方法更符合JavaScript的精神,我更喜欢使用 (2). 为了获得更权威的意见, Douglas Crockford The Good Parts book 2 .


    1 函数语句 (见 @Tim Down's 评论如下)。
    2 实际上有些浏览器能够处理 在里面 如果 声明(再次参考下面的评论)。
    JavaScript: The Good Parts

        2
  •  2
  •   Alex Wayne    14 年前
    function foo() {};
    foo.toString() //-> "function foo() {}"
    
    var bar = foo;
    bar.toString() //-> "function foo() {}"
    

    所以它声明了一个命名函数。无论哪个变量指向它,它的名称都会被保留。另一种语法是匿名函数,它是匿名的,只有在被变量引用时才能被访问。

    var foo = function() {};
    foo.toString() //-> "function () {}"
    
    var bar = foo;
    bar.toString() //-> "function () {}"
    

    var MyThingy = {
      foo: function() { alert('foo') },
      bar: function() { MyThingy.foo() }
    }