在JavaScript中定义的本地功能:使用VAR或没有?(Define local functio

2019-09-02 06:06发布

当本地(内部)函数在JavaScript中声明,有两种选择:

与声明var关键字,分配给变量:

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

声明正好与function关键字,不分配给变量:

(function() {
    function innerFunction2() { ... };
    innerFunction2();
}());

我可以看到第二的一个优点:该函数可以调用它,这样它更容易私有函数从实际执行的代码分开的代码如下声明。

这其中的为什么

Answer 1:

其实有3种方式来声明函数:

  1. 函数声明 :在函数声明定义,而不需要变量赋值命名函数的变量。 函数声明发生作为独立的构建体和不能嵌套非功能块内。 例如: function innerFunction1 () { };

  2. 函数表达式: :函数表达式定义了一个函数作为一个更大的表达式语法(通常是变量赋值)的一部分。 通过函数表达式定义函数可以被命名或匿名:

    一个。 使用匿名功能- var innerFunction1 = function() { };

    湾 使用命名功能- var innerFunction1 = function myInnerFunction () { };

  3. 函数构造 :一个功能构造定义动态使用功能()构造的函数。 需要注意的是,函数体被传递给函数的字符串参数。 var innerFunction1 = new Function (arg1, arg2, ... argN, functionBody)

不建议,因为传递函数体作为字符串可以防止一些JS发动机优化的第三种方法,它是易于出错。

函数声明和函数表达式之间的差别很微妙,你应该选择哪种方法适合您的要求最好的。

我用的函数表达式,我需要

  1. 一个单功能 ,或
  2. 以确定哪个功能是编程方式使用(使用命名的函数表达式)。

函数声明和函数表达式之间的某些区别是:

  1. 函数表达式允许你在不同的点分配不同的功能到相同的变量。
  2. 由函数声明中定义的函数可以函数声明本身(或者在目前的范围基本上任何位置)之前被使用,而由一个函数表达式定义的函数只能定义它的点后使用。

点击这里阅读功能宣言VS函数表达式的详细比较 VS功能构造@MDN

注意:函数声明可以通过将其分配给一个变种被容易地变成一个函数表达式。

function foo() {}
alert(foo); // alerted string contains function name "foo"
var bar = foo;
alert(bar); // alerted string still contains function name "foo"

更多阅读:

  • http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html
  • http://javascriptweblog.wordpress.com/2010/07/06/function-declarations-vs-function-expressions/
  • http://msdn.microsoft.com/en-us/library/ie/x844tc74%28v=vs.94%29.aspx
  • http://es5.github.io/#x15.3
  • VAR functionName =函数(){} VS功能使用functionName(){}


Answer 2:

这两个符号在功能上等同。

你可以假设:

function a() {}
function b() {}

被解释为:

var a, b;
a = function a() {};
b = function b() {};

这就是为什么你之前使用不必宣布─(不定义!)。 您可以重新分配功能,您已经定义了他们之后,就像你会与一个变量。 功能得到升起就像变量,因为它们是变量 (头脑=吹?好!)。


声明-前使用

function a() { b(); } // using b before it's declared?
function b() {}

变为:

var a, b;
a = function a() { b(); }; // nope! b is declared, we're good
b = function b() {};

重新定义的函数

function a() { alert("a"); }
a = function b() { alert("b"); }; // that's weird!

变为:

var a;
a = function a() { alert("a"); };
a = function b() { alert("b"); }; // oh, that looks normal

声明VS定义

声明是: var x 。 在英语:“我会用变量x ”。

定义是: x = 5 。 在英语中“变量x现在拥有价值5 ”。

声明-之前使用的需要,并在强制执行"use strict" 。 定义-之前使用的是不需要的。 如果您的变量在运行时定义你是好。

所以var x = 5 既是声明和一个定义,是function a() {}

命名功能无法覆盖现有的变量时一定要小心:

var a = function () { alert("a"); };
var b = function a() { alert("b"); };
a(); // prints "b"

林特工具将拿起这一点。


当要使用的符号?

我会建议使用的函数表达式表示法( var a = function () {}仅当您重新分配的值a以后。 那么函数表达信号给读者a是会得到重新分配,它是故意的

对于函数表达式表示法的另一个(未成年人)的说法是棉绒工具,如JSLint的可能需要您声明(没有定义!)你的函数然后再使用它们。 如果你有一个递归定义,即功能。 abb调用a ,你不能使用函数声明符号声明一个先于另一个。

编辑指出:我做了关于命名匿名函数略加修改。 当你正在寻找一个堆栈跟踪它可以是有用的命名匿名函数。 在命名的功能将给予更多的情况下,以免被记录为“匿名”。



Answer 3:

所不同的是与该功能VAR运行时被定义,

而功能(),而不VAR在分析时定义为一个脚本块。

这是唯一的主要区别..

因此,用户将决定需求的基础上,其使用上,以及适合需求..



Answer 4:

没有输出任何区别。 双方仍然可以调用,都可以有自己的原型按名称访问。

只有两个真正的差异。

1)可读性和偏好

有些人发现的一种方式比别人更容易阅读,他们会反过来基地,他们约定在该风格。 以下约定是很重要的。

2) 轻微节省空间

随着缩小是以往任何时候都更加脚本相关的,你可以看到,因为它不需要使用它如何可能有利的是使用第二种方法var=这将节省一个基本微不足道4个字符的空间,在你精缩脚本。


执行摘要

这一切都归结为偏好。 哪个更好? 你告诉我。 就个人而言,我会用var如果我打算做一个对象了它与new ,然后我将首字母大写,如人。 否则,我倾向于驼峰,并省略使用的var



Answer 5:

  • var无函数名

    • 是,如果你掌握你的变量声明好:在声明尤其如此。


  • 没有命名函数var

    • 在当前范围的开始意味着这样命名变量声明,它可以从一些错误预防,
    • 但是 :声明一个函数这种方式,使用已宣告封闭变量var如果之前关闭变量甚至宣称这个函数被调用将失败。 所以,你要知道你做了什么。


  • 功能命名,或不var

    • 有利于类的声明,
    • 并剖析原因,例如,Chrome浏览器开发分析工具将是,如果功能不匿名更加明确:他们将有一个明确的名称,你会知道哪里是你的代码的缓慢部分。


  • 功能命名,并用var

    • 是具有该功能的命名范围的方式,而不必声明的变量作为一个封闭
    • 同时保持变量声明秩序的掌握。


Answer 6:

本地声明应该总是使用VAR。

嗯,我会说,首先是更好,因为它是一个局部范围内存可符号使用不超过之后被清除。

还有对谷歌的说明JavaScript的风格指南说,第二种形式是不是标准的一部分,所以它不应该被使用。

功能声明中块

不要这样做:

如果(x)的{函数foo(){}}当块内的最脚本引擎支持函数声明它不是ECMAScript中的一部分(参见ECMA-262中第13和14)。 更糟的是实现彼此并与未来的EcmaScript建议不一致。 ECMAScript中只允许在脚本或函数的根语句列表函数声明。 代替使用与函数表达式初始化的变量块内定义一个函数:

如果(x)的{

VAR富=函数(){}

}

来源http://google-styleguide.googlecode.com/svn/trunk/javascriptguide.xml 。



Answer 7:

与@MarmiK同意。 还两种方法之间的差异的范围。 虽然函数声明默认分配本地范围,分配给一个变量的函数的范围依赖于可变的范围。

var a;
(function() {
    var innerFunction1 = function() { ... };//local scope
    a=innerFunction1;//assigning to a global variable
}());

可以在全球范围进行访问。 与函数声明去,如果你不需要改变的范围。 https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope

编辑:

var a;
(function() {
    function innerFunction1() { ... };//local scope
    a=innerFunction1;//It works too(Don't know why it should though)
}());

因此,由@Frits指出的那样,似乎是在使用一种比其他任何余地的优势。



Answer 8:

Zakas说,“只要你总是定义它们使用之前的功能,你可以随意使用任何函数声明或函数表达式。”

这意味着,如果你的代码将在明天的你不知道有一天另外一个人而改变,这是一个大项目,开发商不能找到在声明函数时,你必须使用函数声明(我的意思是函数x(){} ),或者如果你声明的功能第一,无论如何,你可以使用表达式。



Answer 9:

我认为,大家谁在JavaScript编程开始问这个问题自己迟早的事。 我将再次表述你的问题:

我应该用(喜欢用) 函数声明 (function语句 )或函数表达式 (VAR版本)?

在大多数情况下,可以只使用一个从结构编写好的JavaScript代码。 很明显,有语义一些重要的差异,但我想强调的是,在我看来,对这个问题的答案主要是关于节目风格的答案。 所以,我会回答, 在最真实案例选择口味的问题

谁喜欢使用函数语句的人用它主要不是当他们需要定义只读函数的变量,而不是他们为什么不想宣布将使用它。 在我看来之一,因为一个喜欢的形式使用它所以多半。

所以,我认为有对您的问题没有客观正确的答案。 选择是主观的 。 所以,我写我的答案,建设我个人比较喜欢和哪些情况。

我的第一语言是帕斯卡,C,Fortran语言,C ++等。我现在用用C#。 所以,当我开始写我在从其他语言编写的程序的开始我现有的方式是使用JavaScript程序。 后来我改变了我的JavaScript代码风格对应语言的具体。

个人更喜欢使用函数表达式的风格,我宣布在外部函数的第一个语句的所有功能。 我发现,大部分的形式明确对JavaScript的语义在函数的名称是变量包含一个函数值。 函数的名称是受吊装像任何其他变量。 例如我的代码看起来像下面

(function() {
    "use strict";
    var myFunc1 = function (x) {
            // body where I can use x and this
            alert("x=" + x + ", this.foo=" + this.foo);
        },
        localVar1 = {foo: "bar"};

    myFunc1.call(localVar1, 1);
}());

我用函数语句很少且仅当我宣布类的构造函数,如:

(function() {
    "use strict";
    function MyClass(x) {
        // the code of constructor
        this.abc = x;
    }
    var myInstance = new MyClass("xyz");
    alert(myInstance.abc);
}());

我从来没有尝试用第三种形式:

(function() {
    "use strict";
    var myFunc1 = function myFunc2(x) {
            ...
        };
    ...    
}());

其中myFunc2被另外一个声明myFunc1 。 这种形式的实现取决于从网络浏览器。 它的感觉可能在使用递归函数的情况。



Answer 10:

定义javascript函数

正如维加提到的,有定义一个函数的3种方式:

  1. 构造函数
  2. 函数声明
  3. 函数表达式

功能构造的缺点:

功能需要构造函数体作为一个字符串:

  • 可以防止一些JS引擎优化
  • 使语法天昏地暗写:需要转义特殊字符及其他一些疯狂,见下文

    var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();

    foo(); // The segment "function() {\n\talert(bar);\n}" of the function body string is not re-parsed.

函数声明的缺点:

它可以在函数声明本身之前被调用,这实际上引入了复杂性:

  • 如果你这样做的另一个函数内一个新的函数声明,你怎么能达到你的新功能? 看到jQuery的文件准备和功能范围
  • 为什么一个函数声明是可调用之前JavaScript时的其余部分不同的行为定义它?
  • 你可知道,在后台“函数声明还创建了一个变量具有相同的名称作为函数名”!?
  • 如果使用相同的名称作为函数声明一个变量之前(或之后)定义会发生什么?
  • 可当我用一对括号suround是我的函数的定义仍然被调用? http://jsbin.com/makipuxaje/1/edit?js,console与http://jsbin.com/demecidoqu/1/edit?js,console与http://jsbin.com/xikufakuwo/1/edit? JS,控制台
  • 这是很容易的函数声明转化为函数表达式,intentionaly ...或错误,你懂的后果是什么? 看到什么是感叹号的功能之前,怎么办? 而且JavaScript的加在函数名称前面的标志
  • JavaScript函数作用域和吊装
  • 为什么我的JavaScript函数的名称冲突?

功能表达的优点:

函数表达式更简单:

  • 你“只知道”什么变量被分配到
  • 你不能调用/引用其功能是它的定义之前赋值给变量,这是使用JavaScript定义的其余部分一致的行为

更多关于:转换函数声明为函数表达式

危险:由于在“函数声明的缺点”提到这可能会导致很多问题,以下是关于这个的更多细节。

这是很容易的函数声明转化为函数表达式。

“A函数声明不再是一个当它要么:成为表达式的一部分不再是‘源元件‘’函数或脚本自身A的’源元件在脚本或功能的非嵌套的语句身体” https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions#Examples_2

“功能陈述受吊装。这意味着,无论在哪里的函数被放置的,它被移动到其被限定的范围的顶部。该松弛,其功能应该在使用之前定义的要求,我认为引线以草率,也禁止使用函数语句的if语句。事实证明,大多数浏览器都允许函数语句中的if语句,但他们应当如何解释有所不同。这就产生了可移植性问题“。 -从书: JavaScript中的好零件


更多关于函数表达式

语法例如为:

 var varName = function [name]([param] [, param] [..., param]) {    /* function expression */
      statements
 }

这里需要注意[name] (只是语法“功能”后):

  • 函数名可以省略 ,在这种情况下,功能变为称作匿名功能
  • “函数名不能被改变,而可变的功能被分配给可重新分配”。
  • “函数名称只能在函数体中使用。” ,您可以使用此功能让函数递归调用本身。

然后使用[name]你可以做奇怪/有趣的东西,如下面。 请注意,我不建议这样做,如果你是新的函数定义。

var count = 0;

var varName = function funcName() {    /* function expression */
  console.log('count is: ' + count );
  if(count<1){
    count++;
    funcName();   /* calls function funcName another time  */
  }
};

varName();    // invokes function funcName via variable varName
funcName();   // throws an error as funcName is not reachable

看到现场演示jsbin.com/gijamepesu/1/edit?js,console

一个典型的实现和用法是如以下。

 var myCoolFunc = function ( username, firstName, lastName ) {    /* function expression */
      console.log('user ' + username + ' has the real full name ' + firstName + ' ' + lastName);
 }

 myCoolFunc();

还有一点要注意:函数表达式可以立即调用,VS函数声明不能​​。 此功能用于IIFE,了解更多关于什么是包裹在匿名函数整个Javascript文件等的目的“(函数(){...})()”?


资源

  • https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Functions_and_function_scope#Function_constructor_vs._function_declaration_vs._function_expression
  • https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions
  • 图书: JavaScript中的好零件


Answer 11:

简短的回答:它不会在代码无所谓,但你应该把var ,使其更具可读性。

龙答:在JavaScript中的局部变量,就像在JavaScript中的全局变量,可以有或没有定义的var 。 因此,该程序的功能不会受到缺少或单词的存在干扰var 。 因为它更容易阅读的代码var ,建议你做把var变量之前,当他们第一次声明。 但是,如果你希望它是不可读的,那么你不应该把var定义一个变量之前。



文章来源: Define local function in JavaScript: use var or not?