函数的三种定义方法分别是:函数定义语句、函数直接量表达式和Function()构造函数的方法,下面依次介绍这几种方法具体怎么实现。
<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>
//求阶乘的函数
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); //控制台输出函数的源代码
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()构造函数很少用到,前两中定义方法使用比较普遍。
我理解的 JavaScript 函数式编程,都认为属于函数式编程的范畴,只要他们是以函数作为主要载体的。
给你的代码增加一点点函数式编程的特性,最近我对函数式编程非常感兴趣。这个概念让我着迷:应用数学来增强抽象性和强制纯粹性,以避免副作用,并实现代码的良好可复用性。同时,函数式编程非常复杂。
Async/await以及它底层promises的应用正在猛烈地冲击着JS的世界。在大多数客户端和JS服务端平台的支持下,回调编程已经成为过去的事情。当然,基于回调的编程很丑陋的。
如果你曾经了解或编写过JavaScript,你可能已经注意到定义函数的方法有两种。即便是对编程语言有更多经验的人也很难理解这些差异。在这篇博客的第一部分,我们将深入探讨函数声明和函数表达式之间的差异。
随着软件应用的复杂度不断上升,为了确保应用稳定且易拓展,代码质量就变的越来越重要。不幸的是,包括我在内的几乎每个开发者在职业生涯中都会面对质量很差的代码。这些代码通常有以下特征:
在js开发中,程序代码是从上而下一条线执行的,但有时候我们需要等待一个操作结束后,再进行下一步操作,这个时候就需要用到回调函数。 在js中,函数也是对象,确切地说:函数是用Function()构造函数创建的Function对象。
这篇文章主要介绍ES5中函数的4种调用,在ES5中函数内容的this指向和调用方法有关。以及ES6中函数的调用,使用箭头函数,其中箭头函数的this是和定义时有关和调用无关。
微软 称excel就实现面向开发者的功能,也就是说我们不仅可以全新定义的公式,还可以重新定义excel的内置函数,现在Excel自定义函数增加了使用 JavaScript 编写的支持,下面就简单介绍下如何使用js来编写excel自定义函数。
这篇文章主要讲解:js立即执行函数是什么?js使用立即执行函数有什么作用呢?js立即执行函数的写法有哪些?
arguments是一个类数组对象。包含着传入函数中的所有参数。但这个对象还有一个名叫callee的属性,该属性是一个指针,指向拥有这个arguments对象的函数。this引用的是函数执行的环境对象(当在网页的全局作用域中调用函数时,this对象引用的就是window)
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!