定义JS函数与函数声明、Function构造函数、函数表达式的比较

使用函数声明( )定义函数,语法如下:

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");
};

构造函数不继承全局范围以外的任何范围。

构造函数定义的函数会被解析多次

函数表达式定义的函数和函数声明定义的函数只解析一次。构造函数定义的函数确实不一样。构造函数调用一次,其中的函数体字符串必须解析一次。

虽然函数表达式每次都会创建一个闭包,但函数体不会重复解析,所以还是比构造函数定义的函数快。

© 版权声明
THE END
喜欢就支持一下吧
点赞237赞赏 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片

    暂无评论内容