函数是可读,可维护和可重用代码的构建块.使用function关键字定义函数.以下是定义标准函数的语法.
function function_name(){//函数体}
要强制执行该函数,必须调用它.这称为函数调用.以下是调用函数的语法.
function_name()
示例:简单函数定义
//define a function function test() { console.log("function called") } //call the function test()
该示例定义了函数测试( ).一对分隔符({})定义函数体.它也被称为功能范围.必须调用函数来强制执行.
成功执行上述代码后会显示以下输出.
function called
函数分类
函数可归类为返回和参数化函数.
返回函数
函数也可以将值与控制一起返回,返回到呼叫者.这些函数称为返回函数.
以下是返回函数的语法.
function function_name() { //statements return value; }
返回函数必须以return语句结束.
函数最多可以返回一个值.换句话说,每个函数只能有一个return语句.
return语句应该是函数中的最后一个语句.
以下代码片段是返回函数的示例 :
function retStr() { return "hello world!!!" } var val = retStr() console.log(val)
上面的例子定义了一个函数将字符串"hello world !!!"返回给调用者.成功执行上述代码后会显示以下输出.
hello world!!!
参数化函数
参数是一种将值传递给函数的机制.参数构成函数签名的一部分.参数值在调用期间传递给函数.除非明确指定,否则传递给函数的值的数量必须与定义的参数数量相匹配.
以下是定义参数化函数的语法.
function func_name( param1,param2 ,…..paramN) { ...... ...... }
示例 : 参数化函数
示例定义了一个函数add,它接受两个参数 n1 和 n2 并打印它们的和.参数值在调用时传递给函数.
function add( n1,n2) { var sum = n1 + n2 console.log("The sum of the values entered "+sum) } add(12,13)
成功执行上述代码后会显示以下输出.
The sum of the values entered 25
默认函数参数
在ES6中,函数允许使用默认值初始化参数(如果没有值传递给它或它是未定义的.以下代码说明了相同的内容.
function add(a, b = 1) { return a+b; } console.log(add(4))
上述函数默认将b的值设置为1.除非明确传递了值,否则该函数将始终将参数b视为值1.成功执行上述代码后会显示以下输出.
5
如果函数显式传递一个值,参数的默认值将被覆盖.
function add(a, b = 1) { return a + b; } console.log(add(4,2))
上面的代码将参数b的值明确设置为2,从而覆盖其默认值.成功执行上述代码后会显示以下输出.
6
Rest参数
Rest参数类似于Java中的变量参数. Rest参数不限制可以传递给函数的值的数量.但是,传递的值必须都是相同的类型.换句话说,rest参数充当相同类型的多个参数的占位符.
要声明rest参数,参数名称前缀为三个句点,称为spread运算符.以下示例说明了相同的内容.
function fun1(...params) { console.log(params.length); } fun1(); fun1(5); fun1(5, 6, 7);
成功执行上述代码后会显示以下输出.
0 1 3
注意 : Rest参数应该是函数参数列表中的最后一个.
匿名函数
调用未绑定到标识符(函数名称)的函数作为匿名函数.这些函数在运行时动态声明.匿名函数可以接受输入和返回输出,就像标准函数一样.初始创建后,通常无法访问匿名函数.
可以为变量分配匿名函数.这样的表达式称为函数表达式.
以下是匿名函数的语法.
var res = function( [arguments] ) { ... }
示例 : 匿名函数
var f = function(){ return "hello"} console.log(f())
成功执行上述代码后会显示以下输出.
hello
示例 : 匿名参数化函数
var func = function(x,y){ return x*y }; function product() { var result; result = func(10,20); console.log("The product : "+result) } product()
以下输出是成功执行上述代码时显示.
The product : 200
函数构造函数
函数语句不是定义新函数的唯一方法;您可以使用Function()构造函数和new运算符动态定义函数.
以下是使用Function()构造函数和new运算符创建函数的语法.
var variablename = new Function(Arg1, Arg2..., "Function Body");
Function()构造函数需要任意数量的字符串参数.函数的主体是最后一个参数 - 它可以包含任意的JavaScript语句,用分号相互分隔.
Function()构造函数不传递任何指定名称的参数它创造的功能.
示例 : 函数构造函数
var func = new Function("x", "y", "return x*y;"); function product() { var result; result = func(10,20); console.log("The product : "+result)} product()
在上面的例子中,Function()构造函数用于定义匿名函数.该函数接受两个参数并返回其产品.
成功执行上述代码后会显示以下输出.
The product : 200
递归和JavaScript函数
递归是一种迭代的技术通过使函数自身重复调用直到它到达结果为止来进行操作.当您需要使用循环内的不同参数重复调用相同的函数时,最好应用递归.
示例 : 递归
function factorial(num) { if(num<=0) { return 1; } else { return (num * factorial(num-1) ) } } console.log(factorial(6))
在上面的例子中,函数调用自身.成功执行上述代码后会显示以下输出.
720
示例 : 匿名递归函数
(function() { var msg = "Hello World" console.log(msg)})()
该函数使用一对括号()调用自身.成功执行上述代码后会显示以下输出.
Hello World
Lambda函数
Lambda是指编程中的匿名函数. Lambda函数是表示匿名函数的简明机制.这些函数也称为箭头函数.
Lambda函数 - 解剖
Lambda函数有3个部分 :
参数 : 函数可以选择包含参数.
胖箭头符号/lambda符号(=>):它也被称为转到运营商.
声明 : 表示函数的指令集.
提示 : 按照惯例,鼓励使用单个字母参数来进行紧凑而精确的函数声明.
Lambda表达式
这是一个匿名函数表达式这指向一行代码.以下是相同的语法.
([param1, parma2,…param n] )=>statement;
示例 : Lambda Expression
var foo = (x)=>10+x console.log(foo(10))
示例声明了一个lambda表达式函数.该函数返回10的总和和传递的参数.
成功执行上述代码后显示以下输出.
20
Lambda语句
这是一个匿名函数声明,指向一个块代码当函数体跨越多行时使用此语法.以下是相同的语法.
( [param1, parma2,…param n] )=> { //code block }
示例 : Lambda语句
var foo = (x)=>10+x console.log(foo(10))
返回函数的引用,存储在变量msg中.成功执行上述代码后会显示以下输出.
function invoked
语法变体
单个参数的可选括号.
var msg = x=> { console.log(x) } msg(10)
单个语句的可选括号.没有参数的空括号.
var disp = ()=>console.log("Hello World") disp();
函数表达式和函数声明
函数表达式和函数声明不是同义词.与函数表达式不同,函数声明由函数名绑定.
两者之间的根本区别在于,函数声明在执行之前被解析.另一方面,仅当脚本引擎在执行期间遇到函数表达式时才解析函数表达式.
当JavaScript解析器在主代码流中看到函数时,它假定函数声明.当函数作为语句的一部分出现时,它是一个函数表达式.
函数提升
与变量一样,函数也可以被提升.与变量不同,函数声明在提升时提升函数定义而不是仅仅提升函数的名称.
以下代码片段说明了JavaScript中的函数提升.
hoist_function(); function hoist_function() { console.log("foo"); }
成功执行上述代码后会显示以下输出.
foo
但是,函数表达式无法提升.以下代码片段说明了相同的内容.
hoist_function();//TypeError:hoist_function()不是函数 var hoist_function()= function(){ console.log("bar"); };
立即调用函数表达式
立即调用函数表达式(IIFE)可用于避免块内的变量提升.它允许公共访问方法,同时保留函数中定义的变量的隐私.此模式称为自执行匿名函数.以下两个例子更好地解释了这个概念.
示例1:IIFE
var main = function() { var loop = function() { for(var x = 0;x<5;x++) { console.log(x); } }(); console.log("x can not be accessed outside the block scope x value is :"+x); } main();
示例2:IIFE
var main = function() { (function() { for(var x = 0;x<5;x++) { console.log(x); } })(); console.log("x can not be accessed outside the block scope x value is :"+x); } main();
两个示例都将呈现以下输出.
0 1 2 3 4 Uncaught ReferenceError: x is not define
生成器函数
当调用普通函数时,控件依赖于被调用的函数,直到它返回为止.使用ES6中的生成器,调用函数现在可以控制被调用函数的执行.生成器就像常规函数一样,除了 :
该函数可以在任何时候将控制权交还给调用者.
当您调用生成器时,它不会立即运行.相反,你得到一个迭代器.该函数在调用迭代器的下一个方法时运行.
生成器用函数关键字后缀星号表示;否则,它们的语法与常规函数相同.
以下示例说明了相同的内容.
"use strict" function* rainbow() { // the asterisk marks this as a generator yield 'red'; yield 'orange'; yield 'yellow'; yield 'green'; yield 'blue'; yield 'indigo'; yield 'violet'; } for(let color of rainbow()) { console.log(color); }
生成器启用调用者和被调用函数之间的双向通信.这是通过使用 yield 关键字来实现的.
请考虑以下示例 :
function* ask() { const name = yield "What is your name?"; const sport = yield "What is your favorite sport?"; return `${name}'s favorite sport is ${sport}`; } const it = ask(); console.log(it.next()); console.log(it.next('Ethan')); console.log(it.next('Cricket'));
生成器函数的顺序如下 :
发电机开始暂停;返回迭代器.
it.next()产生"你叫什么名字".发电机暂停.这是由yield关键字完成的.
调用it.next("Ethan")将值Ethan分配给变量名称并产生"你是什么?最喜欢的运动?"发电机再次暂停.
调用it.next("Cricket")将值Cricket分配给变量运动并执行后续运动return语句.
因此,上述代码的输出将为 :
{ value: 'What is your name?', done: false } { value: 'What is your favorite sport?', done: false } { value: 'Ethan\'s favorite sport is Cricket', done: true }
注意 : 无法使用箭头函数表示生成器函数.