函数
一、函数的基础介绍
为什么需要函数
函数最大的好处就是可以对代码实现复用。相同的功能不用 再次书写,而是只用书写一次就够了。这其实就是编程里面所谓的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函数,返回一个数组,这个数组是每次调用函数后的运行结果