js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别

js中有两种声明函数的方法,分别为:

var functionOne = function() {
    // Some code
};

function functionTwo() {
    // Some code
}

为什么会有两种不同的方法?每个方法的优点和缺点分别是什么?有什么情况是一种方法能完成而另外一种方法不能完成的吗?

答:

by @Greg

不同点在于functionOne只会在到达赋值的那一行才会被真正定义,而functionTwo会在 包含它的函数或script脚本 执行的时候马上被定义。例如:

 1 <script>
 2   // Error undefined
 3   functionOne();
 4
 5   var functionOne = function() {
 6   };
 7
 8   // No error
 9   functionOne();
10 </script>
11
12 <script>
13   // No error
14   functionTwo();
15
16   function functionTwo() {
17   }
18 </script>

这也意味着你不能在条件语句中使用第二种方法定义函数:

<script>
  if (test) {
     // Error or misbehavior
     function functionThree() { doSomething(); }
  }
</script>

上面的例子无论test的值是真是假,实际上已经定义了functionThree函数。

by @Eugene Lazutkin

另外,也可以结合以上两种函数定义方法:

var xyz = function abc(){};

xyz 函数将会正常定义。而 abc 函数不会在浏览器中定义(除了IE浏览器),但是在其函数体内可见:

var xyz = function abc(){
  // xyz is visible here
  // abc is visible here
}
// xyz is visible here
// abc is undefined here

如果你想在所有浏览器中使用函数别名,可以使用这种声明方式:

function abc(){};
var xyz = abc;

这种情况下 xyz 和 abc 是同一个函数对象的别名:

console.log(xyz === abc); // prints "true"

使用第二种方式进行函数定义的一个说服性理由是,该函数对象有"name"属性(IE不支持)。当你定义一个类似下面的函数:

function abc(){};
console.log(abc.name); // prints "abc"

函数的name属性会被自动分配。但是当你以下面的方式定义函数:

var abc = function(){};
console.log(abc.name); // prints ""

它的name属性为空——这里创建了一个匿名函数,并将它赋值给其他变量。

推荐使用第二种函数定义方法的另一个理由是,可以用一个简短的内部名称来引用函数本身,同时为外部用户提供一个长的无冲突的别名:

// Assume really.long.external.scoped is {}
really.long.external.scoped.name = function shortcut(n){
  // Let it call itself recursively: 循环调用其本身
  shortcut(n - 1);
  // ...
  // Let is pass itself as a callback: 作为回调函数来传参
  someFunction(shortcut);
  // ...
}

在上面的例子中我们可以用一个外部声明来做和原函数相同的事,但是这样做不方便(同时太慢)。

(引用函数本身的其他方法是使用arguments.callee,这种方法比较常见<不知道这么翻译对不对>,并且在严格模式中不支持)。

实际上,javaScript对两种函数声明方法对待不同。这是一个函数声明:

function abc(){}

这里的abc在目前的范围中是处处都有定义的:

// We can call it here
abc(); // Works

// Yet, it is defined down there.
function abc(){}

// We can call it again
abc(); // Works

同样,它也会透过一个return语句被提前定义:

// We can call it here
abc(); // Works
return;
function abc(){}

另外一个函数表达式:

var xyz = function(){};

这里的xyz在声明行被定义:

// We can‘t call it here
xyz(); // UNDEFINED!!!

// Now it is defined
xyz = function(){}

// We can call it here
xyz(); // works

对函数(function)表达式和函数(Function)声明,我更倾向 "函数表达式" 声明(第一种方式),因为这种方式我可以控制可见性。当我定义这样一个函数:

var abc = function(){};

我知道我定义了一个局部函数。当我定义一个这样的函数:

abc = function(){};

我知道我定义了一个全局函数,并且我没有在作用域链的任何位置定义abc<不太清楚如何翻译>。然而像下面的定义方式:

function abc(){};

原文地址:https://www.cnblogs.com/Fooo/p/9212315.html

时间: 2024-10-14 01:33:06

js中 var functionName = function() {} 和 function functionName() {} 两种函数声明的区别的相关文章

js中构造函数的原型添加成员的两种方式

首先,js中给原型对象添加属性和方法. 方式一:对象的动态特效 给原型对象添加成员 语法:构造函数.prototype.方法名=function (){ } 方式二:替换原型对象(不是覆盖,而是替换,把原先的同名的直接替换成现在的) 语法:构造函数.prototype.方法名={ } tips:方式二不常用,因为这样会修改了原型本身 搜索:JS中通过构造函数添加成员方法和通过原型法添加成员方法的区别 参考网址  http://blog.csdn.net/xxmzumeng/article/det

JS中如何在外部引用私有变量的两种方法 复习

引用:https://blog.csdn.net/liwenfei123/article/details/77964222 运用闭包的特权方法 在构造函数中定义特权方法 这种模式在构造函数中定义了所有私有变量和函数. 能够在构造函数中定义特权方法是因为特权方法作为闭包,能够访问在构造函数中定义的所有变量和函数. function product(){ var name='yuxiaoliang'; this.getName=function(){ return name; } } var obj

js 中var that=this

js中经常出现var that=this,为什么这么做? http://stackoverflow.com/questions/4886632/what-does-var-that-this-mean-in-javascript 问题,回答: 一个回答:$('#element').click(function(){ // this is a reference to the element clicked on var that = this; $('.elements').each(funct

Javascript使用function创建类的两种方法

1.使用function类 //myFunction.js var CMyFunc=function() { //类的公共方法,供外部调用 this.Func1=function() { var i=0; return i; } this.Func2=function() { _privateFunc(); } //类中的私有方法,供公共方法调用 function _privateFunc() { return 0; ] } CMyFunc myFunc=new CMyFunc(); 使用:其它

js中斐波拉切数的三种写法;

js中斐波拉切数的三种写法: function factorial(num){ if(num <=1){ return 1; }else{ return num* factorial(num-1); } } console.log(factorial(5));//120 面这个函数的执行与函数名紧紧耦合在了一起,可以使用arguments.callee可以消除函数解耦 第二种(在严格模式下,访问这个属性会抛出TypeError错误) function factorial(num){ if(num

js函数表达式和函数声明的区别

我们已经知道,在任意代码片段外部添加包装函数,可以将内部的变量和函数定义"隐 藏"起来,外部作用域无法访问包装函数内部的任何内容. 例如: var a = 2; function foo() { // <-- 添加这一行 var a = 3; console.log( a ); // 3 } // <-- 以及这一行 foo(); // <-- 以及这一行 console.log( a ); // 2 虽然这种技术可以解决一些问题,但是它并不理想,因为会导致一些额外的

Android中EditText显示明文与密文的两种方式

效果图   布局文件 <?xml version="1.0" encoding="utf-8"?> <!-- Android中EditText显示明文与密文的两种方式 --> <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/to

【转】oracle 中随机取一条记录的两种方法

oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COUNT(*) INTO V_COUNT FROM  TBL_MYTABLE; SELECT TRUNC(DBMS_RADOM.VALUE(1,V_COUNT+1)) INTO V_NUM FROM DUAL; SELECT * FROM TBL_MYTABLE T WHERE T.FID=V_NUM;

[转]在计算机程序中,完成重复的任务有两种方式:递归和迭代(循环)。

在计算机程序中,完成重复的任务有两种方式:递归和迭代(循环) 递归的一个例子:从前有座山,山里有座庙,庙里一个老和尚在给小和尚讲故事,内容是“从前有座山,山里有座庙,庙里一个老和尚在给小和尚讲故事,内容是“从前有座山,山里有座庙,庙里一个老和尚在给小和尚讲故事,内容是“...... 循环的一个例子:炉子上有99锅汤,让我不小心喝了一锅,炉子上还有98锅汤;炉子上有98锅汤,让我不小心喝了一锅,炉子上还有97锅汤;炉子上有97锅汤,让我不小心喝了一锅,炉子上还有96锅汤; ...... http: