JavaScript中的函数

函数

一、函数的基础介绍

为什么需要函数

函数最大的好处就是可以对代码实现复用。相同的功能不用 再次书写,而是只用书写一次就够了。这其实就是编程里面所谓的DRY原则

声明函数的方式

字面量声明函数

这种方式是用得最为广泛的一种方式,使用关键字function来创建一个函数,具体的语法如 下:

function函数名(形式参数){//函数体}

函数名:就是我们调用函数时需要书写的标识符;

形式参数:简称形参,是调用函数时需要接收的参数;

实际参数:简称实参,是调用函数时实际传递过去的参数

函数表达式声明函数

第二种方式是使用函数表达式来进行声明,具体的语法如下:

let 变量 =function(){

//函数体

}

函数表达式示例:

let test = function(name){

console.log("Hello,"+name);

} test("xiejie");//Hello,xiejie

构造器声明函数

使用构造器来声明函数,又被称之为通过对象的方式来声明函数,具体的语法如下;

let变量=new Function(“参数","参数","函数体”);

函数的调用

写上函数名或者变量名,后面加上 —对大括号;需要注意的是,一般来讲函数表示的是一个动作,所以在给函数命名的时候, —般都是以动词居多。

还一个地方需要注意,那就是如果要调用函数,那么就必须要有括号。这个括号要么在函数名后 面,要么在变量名后面,这样才能够将调用函数后的执行结果返回。如果缺少了括号,那就只是 引用函数本身。

示例如下:

let test = function(){ console.log("Hello");

}

let i = test;//没有调用函数,而是将test函数赋值给了i i();//Hello

函数的返回值

函数的返回值的关键字为return。代表要从函数体内部返回给外部的值

return关键字只能返回一个值,如果想要返回多个值,可以考虑返回一个数组,示例如下: //1-60的安全数7的倍数或者以7结尾

let test = function(){ let arr = [];

for(let i=1;i<=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 ]

函数的参数

形式参数

形式参数简称形参,它就是一种变量,但是这种变量只 能被函数体内的语句使用,并在函数调用时被赋值。JavaScript中的形参的声明是不需要添加关键字的如果加上关键字反而会报错

1、参数名可以重复,同名的参数取最后一个参数值

2、即使函数声明了参数,调用时也可以不传递参数值

3、调用函数时可以传递若干个参数值给函数,而不用管函数声明时有几个参数

arguments伪数组对象, 注:不是数组

function test(x){

for(let i=0;i<arguments.length;i++){

console.log(arguments[i]);

}

}

test(1,2,3);

不定参数

不定参数是从ES6开始新添加的功能,在最后一个形式参数前面添加3个点,会将所有的实参放 入到一个数组里面,

示例如下:

function test(a,...b){

console.log(a);//1

console.log(b);//[2,3]

test(1,2,3);

这里的不定参数就是一个真正的数组;还有一点需要注意的是,不定参数都是放在形式参数的最后面,如果不是放在最后,则会报错。

默认参数

从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

函数的属性和方法

1.name 属性

表示函数的函数名

function test(){ console.log("Hello");}

console.log(test.name);//test

2.length 属性

表示形式参数的个数

let test = function(a,b,c){

console.log("Hello");

}

console.log(test.length);//3

函数名.length与arguments.length的区别 函数对象的length属性是表示形式参数的个数。

arguments伪数组对象的length属性是调用函数时实际参数的个数。

let test = function(a,b,c){

console.log(arguments.length);//5

console.log(arguments.callee.length);//3

}

test(1,2,3,4,5)

二、箭头函数

1.箭头函数基本介绍

箭头函数,是从ES6开始新增加的一种声明函数的方式。其最大的特点在于不需要function 关键字,取而代之的是使用一个=> 来进行表示。箭头函数的基本语法如下:

let变量=(形式参数)=> {

//函数体

}

箭头函数示例:

let test = (name) => {

console.log("Hello",name);

}

test("xiejie");//Hello xiejie

上面所介绍的,只是箭头函数的基本写法。实际上箭头函数根据形式参数和函数体的不同,书写 的方式拥有一些变形。如下:

//如果没有参数

let 变量=()=> {

//函数体

}

//如果只有一个形参

let变量=形参=> {

//函数体

}

//如果函数体只有一个返回值

let 变量=形参=> expression

例如:书写求立方根的箭头函数(当然这里只是练习,ES6已经提供了求黑的方式,使用**)

let test = x => x*x*x;

console.log(test(3));//27

2.箭头函数的优点

箭头函数的优点如下:

比普通函数声明更简洁

只有一个形参就不需要用括号括起来

如果函数体只有一行,就不需要放到一个块中

如果return语句是函数体内唯一的语句,就不需要return关键字

不会把自己的this值绑定到函数上

三、提升

1、作用域

全局作用域:这个是默认的代码运行环境,一旦代码被载入,引擎最先进入的就是这个环境。

函数作用域:当进入到一个函数的时候,就会产生一个函数作用域

eval作用域:当调用eval。函数的时候,就会产生一个eval作用域

2、变量提升

所谓变量提升,就是指在使用var关键字进行变量声明的时候,默认会将声明变量的部分提升至 当前作用域的最顶上,但是注意提升的只有变量的声明部分,赋值是不会提升的

3、函数提升

所谓函数提升,是指当我们使用字面量方式来声明一个函数的时候,此时函数的声明会提升到当 前作用域的最顶端,这意味着我们可以将函数的调用书写到函数的声明之前

四、回调函数

1回调函数基本介绍

所谓回调函数,通俗的来讲,就是指将一个函数作为参数传递给另外一个函数,然后在另外一个 函数里面执行传递过去的函数

2常见回调函数介绍

回调函数我们在之前的学习中就已经见到过了。就在我们使用sort()为数组进行排序的时候,默认是使用的ASCII码来进行的排序。如果想要按照数值来进行排序,就需要我们传递一个 回调函数进去。

迭代方法

every():对数组的每一项运行给定的函数,如果该函数每一项都返回true,则返回true

some(),该方法可以对数组的每一项运行指定的函数,如果该函数只要有 —项返回true则返回true

filter(): filter是过滤的意思,所以这个方法会返回一个数组,数组里面是返回true的元素

forEach():这个方法我们在前面介绍数组遍历的时候,就已经见到过了。该方法就是简单的将数 组每一项传入到函数,然后执行该函数里面的代码。需要注意一下的是,该回调函数没有返回 值。

map():对数组的每一项运行test函数,返回一个数组,这个数组是每次调用函数后的运行结果