使用函数声明( )定义函数,语法如下:
function name([param,[, param,[..., param]]]) { [statements] }
函数表达式
函数表达式与函数声明非常相似,只是函数表达式可以省略函数名来定义匿名函数。
函数表达式语法结构如下:
function [name]([param1[, param2[, ..., paramN]]]) { statements }
构造函数
也可以使用new操作符通过构造函数创建:
new Function ([arg1[, arg2[, ...argN]],] functionBody)
注意:构造函数使用字符串作为函数体,这样会阻碍JS引擎的优化,并导致一些其他问题。因此,不推荐这种函数定义方式。
1.2 ES 6 中新的函数定义方法
在 ES 6 ( 2015) 中增加了三个(生成器函数),这个函数也有三个定义:
生成器函数声明 – * 声明
类似于函数声明,只是在关键字后面加了*号:
function* name([param[, param[, ...param]]]) { statements }
生成器函数表达式 – * 表达式
同样,生成器函数也可以使用表达式来定义:
function* [name]([param] [, param] [..., param]) { statements }
生成器函数构造函数-
new GeneratorFunction (arg1, arg2, ... argN, functionBody)
除了生成器函数之外,ES6 还添加了一种更短的方法来定义函数 – 。
箭头函数-=>
([param] [, param]) => { statements } param => expression
2.函数声明、构造函数和函数表达式的比较
函数声明、构造函数和函数表达式的示例如下:
使用构造函数定义一个函数并将其赋值给:
var multiply = new Function("a", "b", "return a * b");
使用函数表达式来定义函数:
function multiply(x, y) { return x * y; }
使用函数表达式定义函数并将其分配给:
var multiply = function(x, y) { return x * y; };
使用函数表达式时,还可以指定函数名。例如,分配一个名为:
var multiply = function func_name(x, y) { return x * y; };
一些差异
构造函数使用字符串作为函数体,防止了JS引擎的语法检查和优化。因此js函数中定义函数,不建议使用此定义。函数声明与函数表达式非常相似,但也有一些区别。这三种方法的不同主要体现在以下几个方面:
函数变量可以重新赋值
用函数声明定义的函数名称不能更改,而用函数表达式定义的函数变量可以重新赋值。函数表达式使用函数名时js函数中定义函数,该名称只能用在函数体中,在其他地方使用会报错:
var y = function x() {}; alert(x); // throws an error
并且’new’没有定义函数名,所以不能在里面访问。
函数声明扩大范围
函数声明会扩大作用域,所以你可以在函数声明之前在函数声明中使用函数名:
hoisted(); // "http://itbilu.com" function hoisted() { console.log("http://itbilu.com"); }
函数表达式将创建一个闭包,该闭包定义了继承当前作用域且不会进行作用域提升的函数:
notHoisted(); // TypeError: notHoisted is not a function var notHoisted = function() { console.log("http://itbilu.com"); };
构造函数不继承全局范围以外的任何范围。
构造函数定义的函数会被解析多次
函数表达式定义的函数和函数声明定义的函数只解析一次。构造函数定义的函数确实不一样。构造函数调用一次,其中的函数体字符串必须解析一次。
虽然函数表达式每次都会创建一个闭包,但函数体不会重复解析,所以还是比构造函数定义的函数快。
暂无评论内容