JavaScript中函数的三种定义方法

更新日期: 2018-04-16 阅读: 5k 标签: 函数

函数的三种定义方法分别是:函数定义语句、函数直接量表达式和Function()构造函数的方法,下面依次介绍这几种方法具体怎么实现。


1. 函数定义语句

<span style="font-size:14px;">//求和函数  
function sum(a,b){  
    return a+b;  
}</span>


这是最典型的函数声明,以关键字function开始,其后跟随函数名称标识符、一对圆括号(包含由0个或多个逗号隔开的参数名称)和一对花括号(包含0条或多条JS语句,构成函数体)。这种函数定义方式需要显式的指定函数名称,在代码执行前就被解释器加载到作用域中,这个特性可以让我们在函数定义之前就调用该函数。我们可以通过代码来验证这一点。

<span style="font-size:14px;">console.log(sum);        //控制台输出sum函数的源代码,此时函数还未定义  
function sum(a,b){  
    return a+b;  
}  
console.log(sum(2,3));   //5</span>


既然提到函数声明,就要提到函数的作用域。函数作用域是指在函数内声明的所有变量在函数体内始终是可见的,这意味着,变量在声明之前已经可用。这个特性可以被称为声明提前,即在函数体内声明的所有变量,在声明之前已经有定义,但只有在执行到这个变量时才会被真正赋值。从以代码可以清晰地看到这一点

<span style="font-size:14px;">var scope = "global";  
function f(){  
  console.log(scope);         //输出“undefined”,而不是“global”  
  var scope = "local";          //变量在这里赋初始值,但变量本身在函数体内任何地方均是有定义的  
  console.log(scope);         //输出“local”  
}  
f();</span>


以上代码等价于

<span style="font-size:14px;">var scope = "global";  
function f() {  
  var scope;                //在函数顶部声明了局部变量,即声明提前  
  console.log(scope);         //变量存在,输出“undefined”,而不是“global”  
  var scope = "local";       //变量在这里赋初始值    
console.log(scope);         //输出“local”  
}  
f();</span>


2. 函数直接量表达式

//求阶乘的函数  
var factorial = function fact(x){   //将函数赋值给一个变量  
    if(x<0) {return NaN;}  
    else if(x===0) {return 1;}  
    else  
    return x*fact(x-1);     //递归函数  
};  
console.log(factorial(3));      //6


与函数定义语句一样,函数直接量表达式也是用到了关键字function。一般这种定义方式适用于将它作为一个大的表达式的一部分,比如在赋值和调用过程中定义函数。通过函数直接量生成的函数,函数名称可以省略,此时就是一个匿名函数。如下例所示:这样可以使代码更为紧凑。函数定义表达式特别适合用来定义那些只会用到一次的函数。

var f=function(x){    //省略函数名的匿名函数  
  return x*x;  
}


与函数定义语句不同的是,函数直接量表达式是在执行到代码时才加载函数的,我们可以用下面的代码来说明。

console.log(f);        //控制台输出undefined,此时函数f还未加载  
var f=function(x){     //开始加载函数  
  return x*x;  
}  
console.log(f);       //控制台输出函数的源代码


3. Function()构造函数

var f = new Function("x","y","return x+y");  //Function()构造函数  
var f = function(x,y){return x+y};  //这两条代码是等价的


Function()构造函数可以传入任意数量的字符串实参,最后一个实参所表示的文本是函数体,可以包含任意数量的JavaScript语句。如果构造的函数不包含任何参数,则只需传入一个函数体即可。与前两者方式不同的是,Function()构造函数允许JavaScript在运行时动态地创建并翻译函数。每次调用Function()构造函数都会解析函数体,并创建新的函数对象。因而,在循环或多次调用的函数中执行这个构造函数,执行效率会受影响。相比之下,循环中的嵌套函数和函数定义表达式则不会每次执行时都重新编译。

Function()构造函数还有值得注意的一点就是它所创建的函数并不是使用词法作用域,函数体代码的编译总在顶层函数执行。如下代码所示:

var a = 3;     //在顶层函数中声明变量a  
function f(){  
    var a = 2;   //在函数体内声明局部变量a  
    return new Function("return a*a;");   //无法捕获局部作用域  
}  
console.log(f()());     //控制台输出9而非4,说明构造函数的编译在顶层函数执行


我们可以将Function()构造函数认为是在全局作用域中执行的eval()。在实际编程中,Function()构造函数很少用到,前两中定义方法使用比较普遍。


本文内容仅供个人学习、研究或参考使用,不构成任何形式的决策建议、专业指导或法律依据。未经授权,禁止任何单位或个人以商业售卖、虚假宣传、侵权传播等非学习研究目的使用本文内容。如需分享或转载,请保留原文来源信息,不得篡改、删减内容或侵犯相关权益。感谢您的理解与支持!

链接: https://fly63.com/article/detial/645

相关推荐

JavaScript push() 方法详解

push() 方法主要用于向数组的末尾添加一个或多个元素,其返回值为添加后新的长度,即push后的数组长度,该值为number类型。介绍:一个数组中添加新元素、把一个数组的值赋值到另一个数组上、在对象使用push

什么是纯函数_以及为什么要用纯函数?

当我第一次听到 “纯函数 (Pure Function)” 这个术语的时候我很疑惑。常规的函数做错了什么?为什么要变纯? 为什么我需要纯的函数?除非你已经知道什么是纯函数,否则你可能会问同样的疑惑

让我们来创建一个JavaScript Wait函数

Async/await以及它底层promises的应用正在猛烈地冲击着JS的世界。在大多数客户端和JS服务端平台的支持下,回调编程已经成为过去的事情。当然,基于回调的编程很丑陋的。

什么是函数的副作用——理解js编程中函数的副作用

函数副作用是指当调用函数时,除了返回函数值之外,还对主调用函数产生附加的影响。副作用的函数不仅仅只是返回了一个值,而且还做了其他的事情

js中sort函数用法总结_sort排序算法原理

js中sort方法用于对数组的元素进行排序,并返回数组。默认排序顺序是根据字符串Unicode码点。如果要得到自己想要的结果,不管是升序还是降序,就需要提供比较函数了。该函数比较两个值的大小,然后返回一个用于说明这两个值的相对顺序的数字

javascript封装函数

使用函数有两步:1、定义函数,又叫声明函数, 封装函数。2、调用函数var 变量 = 函数名(实参);对函数的参数和返回值的理解

js中reduce()方法

reduce() 方法接收一个函数作为累加器,reduce 为数组中的每一个元素依次执行回调函数,不包括数组中被删除或从未被赋值的元素,接受四个参数:初始值(上一次回调的返回值),当前元素值,当前索引,原数组。

javascript回调函数的理解和使用方法(callback)

在js开发中,程序代码是从上而下一条线执行的,但有时候我们需要等待一个操作结束后,再进行下一步操作,这个时候就需要用到回调函数。 在js中,函数也是对象,确切地说:函数是用Function()构造函数创建的Function对象。

js调用函数的几种方法_ES5/ES6的函数调用方式

这篇文章主要介绍ES5中函数的4种调用,在ES5中函数内容的this指向和调用方法有关。以及ES6中函数的调用,使用箭头函数,其中箭头函数的this是和定义时有关和调用无关。

js构造函数

JS中的函数即可以是构造函数又可以当作普通函数来调用,当使用new来创建对象时,对应的函数就是构造函数,通过对象来调用时就是普通函数。在我们平时工作中,经常会需要我们创建一个对象,而我们更多的是使用对像直接量,直接创建

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!