Function构造函数、 函数声明 、 函数表达式 的区别

对比下面的例子:前端

Function构造函数

var multiply = new Function('x', 'y', 'return x * y');
复制代码

函数声明

function multiply(x, y) {
   return x * y;
} // 没有分号
复制代码

函数表达式

var multiply = function(x, y) {
   return x * y;
 };
复制代码

一个命名为func_named的函数的函数表达式,被赋值给变量multiply:

var multiply = function func_name(x, y) {
   return x * y;
};
复制代码

区别

  • 函数名不能被改变,但函数的变量却可以被再分配
  • 函数名只能在函数体内使用
  • 假若在函数体外使用函数名将会致使错误(若是函数以前是经过一个var语句声明的则是undefined)。如:
var y = function x() {};
alert(x); // throws an error
复制代码
  • 函数名和函数的变量存在着差异。函数名不能被改变,但函数的变量却可以被再分配。函数名只能在函数体内使用。假若在函数体外使用函数名将会致使错误
  • 函数名与被函数赋值的变量是不相同的. 彼此之间没有关系
  • 函数声明同时也建立了一个和函数名相同的变量
  • 使用 'new Function'定义的函数没有函数名。在 SpiderMonkey JavaScript引擎中,其函数的序列化形式表现的好像它拥有一个名叫"anonymous"的名称同样,而实际上其函数并无名称,anonymous 不是一个能够在函数内被访问到的变量
  • 和函数表达式或者Function构造函数定义的函数不一样,函数声明的函数能够在它被声明以前使用。如:
// 函数声明
foo() // foo
function foo() {
    return 'foo'
}
// 函数表达式
foo2() // foo2 is not a function
var foo2 = function(){
    return 'foo2'
}
// Function 构造函数  
foo3()  // foo3 is not a function
var foo3 = new Function('return "foo3"')

复制代码
  • 函数表达式定义的函数继承了当前的做用域。换言之,函数构成了闭包。另外一方面,Function构造函数定义的函数不继承任何全局做用域之外的做用域(那些全部函数都继承的)。bash

  • 经过函数表达式定义的函数和经过函数声明定义的函数只会被解析一次,而Function构造函数定义的函数却不一样。闭包

注意在经过解析Function构造函数字符串产生的函数里,内嵌的函数表达式和函数声明不会被重复解析。例如:ide

var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))();
foo(); // 函数体字符串"function() {\n\talert(bar);\n}"的这一部分不会被重复解析。
复制代码

函数声明如何转成函数表达式

  • 成为表达式的一部分
// 函数表达式
var foo = function(){}
var bar = function bar(){}
(function bar2() {})
复制代码
  • 再也不是函数或者脚本自身的“源元素” (source element)。“源元素”是脚本或函数体中的非嵌套语句
var x = 0;               // source element
if (x === 0) {           // source element
   x = 10;               // 非source element
   function boo() {}     // 非 source element 函数表达式
}
function foo() {         // source element   函数声明
   var y = 20;           // source element
   function bar() {}     // source element   函数声明
   while (y === 10) {    // source element
    function blah() {} // 非 source element 函数表达式
     y++;               //非source element
   }
}
复制代码

若有侵权,请发邮箱至wk_daxiangmubu@163.com 或留言,本人会在第一时间与您联系,谢谢!! 函数

关注咱们
长按二维码关注咱们,了解最新前端资讯
相关文章
相关标签/搜索