2013-02-22 84 views
2

JavaScript中两个模块声明有什么区别? 一个在功能周围有括号,另一个没有?javascript中两个声明的区别是什么?

一篇文章说,

公告的()周围的匿名函数。这是由 语言要求的,因为这与令牌功能开始语句 一直被认为是函数声明。包括()会改为创建一个 函数表达式。

似乎都检查什么时候做同样的事情。

var person = (function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName: function() { 
      return name; 
     }, 
     setName: function(newName) { 
      name = newName; 
     } 
    }; 
}()); 

var person = function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName: function() { 
      return name; 
     }, 
     setName: function(newName) { 
      name = newName; 
     } 
    }; 
}(); 
+0

[函数声明](http://ecma-international.org/ecma-262/5.1/#sec-13)都不是函数表达式。 – RobG 2013-02-22 11:53:21

+0

没有区别。 – 2013-02-22 11:53:24

+0

通常第二个需要首先通过'person()'实例化,但也许在运行时环境中存在一个错误。 – 2013-02-22 11:54:13

回答

3

功能有两种类型的JavaScript - 声明和表达式。

这是二者之间的差:

  1. 函数声明悬挂。这意味着您可以在程序出现之前调用该函数,因为在JavaScript中声明已悬挂
  2. 函数表达式可以立即调用。函数声明不能​​。这是因为表达式表示(或返回一个值)。函数表达式表示一个函数。

函数声明的一个例子:

foo("bar"); 

function foo(bar) { 
    alert("foo" + bar); 
} 

上述方案将工作,因为foo是一个函数声明。如foo被声明为undefined,悬挂再后来分配一个函数表达式的值

foo("bar"); // throws an error, foo is undefined - not a function 

var foo = function (bar) { 
    alert("foo" + bar); 
}; 

上述程序将不工作。当它被调用时它是undefined

函数式的一个例子:

(function (bar) { 
    alert("foo" + bar); 
}("bar")); 

上述功能将被立即调用,因为它是一个函数表达式。

function (bar) { 
    alert("foo" + bar); 
}("bar"); // throws an error, can't call undefined 

上述函数不会立即被调用,因为它是一个函数声明。请记住,声明不表示(或返回值)。所以这就像试图调用undefined作为一个函数。

函数如何成为表达式?

如果在预期表达式的上下文中使用函数,那么它将被视为表达式。否则它被视为声明。

  1. 你赋值给一个变量(即identifier = expression):当

    表达式的预期。

  2. 括号内(即(expression))。
  3. 作为操作符的操作数(即operator expression)。

因此,以下是所有函数表达式:

var foo = function() {}; 
(function() {}); 
~function() {}; 

其他的都是一个函数声明。简而言之,如果你的功能没有任何事情发生,它就是一个声明。

看到这个代码:https://github.com/aaditmshah/codemirror-repl/blob/master/scripts/index.js#L94

以下功能isExpression用于测试一些任意JavaScript代码是否是一个表达式或不:

function isExpression(code) { 
    if (/^\s*function\s/.test(code)) return false; 

    try { 
     Function("return " + code); 
     return true; 
    } catch (error) { 
     return false; 
    } 
} 

希望这将清除在你的心中有任何怀疑。

简而言之:

  1. 函数表达式表达或返回一个值(在这种情况下的函数)。因此可以立即调用,但在程序出现之前无法调用它。
  2. 函数声明是的悬挂。因此可以在程序出现之前调用它。但由于它不表示任何价值,因此不能立即调用。
1

不同的是,书写时:

var foo = (function() { 
      ... 
}()); 

使用的(多余的,但很有用)分组()是一种常见的编码风格,使之清楚很像右边第一行很可能是立即调用的函数表达式(IIFE)。然而,在第二:

var foo = function() { 
      ... 
}(); 

它不直到你读的最后一行,这可能是相当多的线下变得明显。直到到达最后一行,你可能以为你在读一个普通的任务:

var foo = function() { 
      ... 
}; 

注意,括号可以在一个普通的分配也可用于:

var foo = (function() { 
      ... 
}); 

,但在这种情况下,他们真的是多余的(并且由于将它们用于IIFE的惯例可能会引起误导)。

An Important Pair of Parens

1

在目前情况下有一个为解释没有区别。写模块通常最好的方式是通过包装用括号功能:

var person = (function() { 
    // Private 
    var name = "Robert"; 
    return { 
     getName : function() { 
      return name; 
     } 
    }; 
}()); 

这是因为语法是更清洁,这显然是要调用它宣布后立即功能。还有一个原因是因为:

(function() { 
    //some stuff 
}()); 

工作,但

function() { 
    //some stuff 
}(); 

这不会。

通过包装在每次使用常见的作弄风格通常是:-)一件好事时间的函数。

相关问题