跳到主要内容

函数定义的5种方式

(一)函数声明(function declarations)

函数名是强制性的,存在变量提升。可以在声明之前进行函数调用

function foo(){ 
return 1;
}


//立即执行函数
(function(e){console.log(e)}())(3);
/* 函数表达式被包裹在一对括号内。为什么这样做呢?其原因是纯语法层面的。JavaScript解析器必须能够轻易区分函数声明和函数表达式之间的区别。如果去掉包裹函数表达式的括号,把立即调用作为一个独立语句function() {}(3),JavaScript开始解析时便会结束,因为这个独立语句以function开头,那么解析器就会认为它在处理一个函数声明。每个函数声明必须有一个名字(然而这里并没有指定名字),所以程序执行到这里会报错。为了避免错误,函数表达式要放在括号内,为JavaScript解析器指明它正在处理一个函数表达式而不是语句。 */

+function(){console.log(1)}();
-function(){console.log(1)}();
!function(){console.log(1)}();
~function(){console.log(1)}();

(二)函数表达式(function expressions)

函数名是可选的

var foo = function(){ 
return 1;
}

(三)箭头函数(通常被叫做lambda函数)

ES6新增的JavaScript标准,能让我们以尽量简洁的语法定义函数。

var foo = () => 1

(四)函数构造函数

不常使用的函数定义方式,能让我们以字符串形式动态构造一个函数,这样得到的函数是动态生成的。使用 new Function 创建函数的应用场景非常特殊,比如需要从服务器获取代码或者动态地按模板编译函数时才会使用,在一般的程序开发中很少使用。

//先传入函数所需的参数(准确地说是形参名),最后传入函数的函数体。传入的所有参数均为字符串。
let func = new Function ([arg1[, arg2[, ...argN]],] functionBody)

// 创建一个包含两个入参的函数
let sum = new Function('a', 'b', 'return a + b');
alert( sum(1, 2) ); // 3

//如果创建出的新函数没有任何入参,那么创建函数时你只需要传入一个参数,即描述新函数中函数体的字符串:
let sayHi = new Function('alert("Hello")');
sayHi(); // Hello

(五)生成器函数

ES6新增功能,能让我们创建不同于普通函数的函数,在应用程序执行过程中,这种函数能够退出再重新进入,在这些再进入之间保留函数内变量的值。我们可以定义生成器版本的函数声明、函数表达式、函数构造函数。

function* foo(){ 
yield 1;
}