函数,是可以通过名称来引用,并且就像自包含了一个微型程序的代码块。利用函数,我们可以 实现对代码的复用,降低代码的重复,并且让代码更加容易阅读。在JavaScript中,函数显得尤 为的重要。因为函数在JavaScript中是一等公民,可以像参数一样传入和返回。所以说函数是 JavaScript中的一个重点,同时也是一个难点。
函数基础介绍:三要素,是指函数的功能,函数的参数,以及函数的返回值。
字面量声明函数:这种方式是用得最为广泛的一种方式,使用关键字function来创建一个函数,具体的语法如 下:
function函数名(形式参数){
//函数体
}
函数名:就是我们调用函数时需要书写的标识符
形式参数:简称形参,是调用函数时需要接收的参数
实际参数:简称实参,是调用函数时实际传递过去的参数
示例:
function test(name){
console.log("Hello,"+name);
}
test("xiejie");//Hello,xiejie
函数表达式声明函数:第二种方式是使用函数表达式来进行声明,具体的语法如下:let 变量 =function(){
//函数体
}
函数表达式示例:
let test = function(name){
console.log("Hello,"+name);
}
test("xiejie");//Hello,xiejie
将一个匿名函数赋值给一 个变量,然后通过这个变量来对函数进行调用。也可以将一个带有名字的函数赋值给一个变量。这样的声明方式被称之为命名式函数 表达式
示例如下:let test = function saySth(name){ console.log("Hello,"+name);
}
test("xiejie");//Hello,xiejie
构造器声明函数:使用构造器来声明函数,又被称之为通过对象的方式来声明函数,具体的语法如下;
let变量=new Function("参数","参数","函数体");
示例如下:
let test = new Function("name","console.log('Hello,'+name)"); test("xiejie");//Hello,xiejie
虽然通过这种方式也能够创建出函数,并且调用,但是并不推荐使用这种方式来创建函数。因为 这样会导致JS解释器需要解析两次代码。先要解析这个表达式,然后又要解析字符串,效率很 低,并且这样将函数体全部书写在一个字符串里面的书写方式对我们程序员也非常的不友好,所 以这种方式作为了解即可。
函数的调用:函数的调用在前面介绍函数声明的时候也已经见到过了,就是写上函数名或者变量名,后面加上 —对大括号即可。需要注意的是,一般来讲函数表示的是一个动作,所以在给函数命名的时候, —般都是以动词居多。
还一个地方需要注意,那就是如果要调用函数,那么就必须要有括号。这个括号要么在函数名后 面,要么在变量名后面,这样才能够将调用函数后的执行结果返回。如果缺少了括号,那就只是 引用函数本身。
示例如下:
let test = function(){
console.log("Hello");
}
let i = test;//没有调用函数,而是将test函数赋值给了i i();//Hello
函数的返回值:函数的返回值的关键字为return。代表要从函数体内部返回给外部的值,示例如下: let test = function(){
return "Hello";
}
let i = test();
console.log(i);//Hello
即使不写return ,函数本身也会有返回值undefined 例如:
let test = function(){
console.log("Hello");
}
let i = test();//Hello console.log(i);//undefined
需要注意的是,return后面的代码是不会执行的,因为在函数里面一旦执行到return ,整个
函数的执行就结束了。
let test = function(){ return 1;
console.log("Hello");
}
let i = test();
console.log(i);//!
return关键字只能返回一个值,如果想要返回多个值,可以考虑返回一个数组,示例如下:
//1-60的安全数7的倍数或者以7结尾
let test = function(){
let arr = [];
for(let i=l;iv=60;i++)
if(i%10==7 || i%7==0)
{ arr.push(i);
}
}
return arr;
}
console.log(test());
//[ 7, 14, 17, 21, 27, 28, 35, 37, 42, 47, 49, 56, 57 ]
函数的参数:1.形式参数:形式参数简称形参,它就是一种变量,但是这种变量只 能被函数体内的语句使用,并在函数调用时被赋值。JavaScript中的形参的声明是不需要添加关 键字的,如果加上关键字反而会报错
示例:
function test(let i){
console.log(i);
}
test(5);
//SyntaxError: Unexpected identifier
JavaScript里面关于函数的形参,有以下几个注意点:
- 参数名可以重复,同名的参数取最后一个参数值
function test (x,x){
console.log(x);
}
test(3,5);//5
- 即使函数声明了参数,调用时也可以不传递参数值
function test(x){
console.log(x);
}
test();//undefined
- 调用函数时可以传递若干个参数值给函数,而不用管函数声明时有几个参数
function test(x){
console.log(x);//l
}
test(1,2,3);
那么,这究竟是怎么实现的呢?为什么实参和形参可以不用一一对应呢?
实际上,当一个函数要被执行的时候,系统会在执行函数体代码前做一些初始化工作,其中之一 就是为函数创建一个argument s的伪数组对象。这个伪数组对象将包含调用函数时传递的所有的 实际参数。因此,arguments的主要用途是就是用于保存传入到函数的实际参数的。
面的例子演示了通过arguments伪数组对象来访问到所有传入到函数的实参
function test(x){
for(let i=0;i<arguments.length;i++){ console.log(arguments[i]);
}
}
test(1,2,3);
// 1
// 2
// 3
所谓伪数组对象,就是长得像数组的对象而已,但是并不是真的数组,我们可以证明这一点
function test(x){
arguments .push( 100); //针对伪数组对象使用数组的方法
}
test(1,2,3);
//TypeError: arguments.push is not a function
不定参数:在最后一个形式参数前面添加3个点,会将所有的实参放 入到一个数组里面,示例如下:
function test(a,...b){
console.log(a);//1
console.log(b);//f2,37
test(1,2,3);
这里的不定参数就是一个真正的数组,可以使用数组的相关方法
function test(a,...b){
console.log(a);//l
console.log(b);//f2,3J
b.push(100);
console.log(b);//f 2, 3, 100 ]
}
test(1,2,3);
还有一点需要注意的是,不定参数都是放在形式参数的最后面,如果不是放在最后,则会报错。
function test(...a,b){
console.log(a);
console.log(b);
}
test(1,2,3);
//SyntaxError: Rest parameter must be last formal parameter
默认参数:从ES6开始,书写函数的时候可以给函数的形式参数一个默认值。这样如果在调用函数时没有传 递相应的实际参数,就使用默认值。如果传递了相应的实际参数,则使用传过去的参数。
function test(name = "world"){
console.log("Hello,"+name);
}
test("xiejie");//Hello,xiejie
test();//Hello,world
如果参数是一个数组,要为这个数组设置默认值的话,写法稍微有些不同,如下:
let fn = function([a = 1,b = 2] = []){
console.log(a,b);
}
fn(); // 1 2
fn([3,4]); // 3 4 包括后面我们要介绍的对象,也是可以设定默认值的,但是写法和上面类似,如下: let fn = function({name = 'xiejie',age = 18} = {}){ console.log(name,age);
}
fn(); // xiejie 18 fn({name:"song",age:20}); // song 20
函数属性和方法:name属性:表示函数的函数名
function test(){
console.log("Hello");
}
console.log(test.name);//test
我们可以通过这个name属性来证明函数表达式的变量不是函数名,如下:
let test = function test2(){ console.log("Hello");
} console.log(test.name);//test2
length 属性:表示形式参数的个数,示例如下:
let test = function(a,b,c){ console.log("Hello");
}
console.log(test.length);//3
接下来我们需要看一下函数名.length与arguments.length的区别 函数对象的length属性是表示形式参数的个数。
argument s伪数组对象的length属性是调用函数时实际参数的个数。
let test = function(a,b,c){
console.log(arguments.length);//5 console.log(arguments.callee.length);//3
}
test(1,2,3,4,5);