箭头函数

定义和调用函数:(传统写法)

1
2
3
4
5
function fn1(a,b){
return a+b;
}

console.log(fn1(1,2));//输出结果:3

定义和调用函数:(ES6中的写法)

1
2
var fn2=(a,b)=> a+b;
console.log(fn2(1,2));//输出结果:3

二者的效果相同。

在箭头函数中,如果方法体内有两句话,那就需要在方法体外加上{}括号。如下:

1
2
3
4
var fn2=(a,b)=>{console.log('haha');
return a+b;
};
console.log(fn2(1,2))//输出结果:3

从上方的箭头函数中,我们可以很清晰的找到函数名,参数名,方法体。

上方代码中:

  • 如果有且仅有1个参数,则()可以省略
  • 如果方法体内仅有1条语句,则{}可以省略,但前提是,这条语句必须是return。

this的指向

箭头函数只是为了让函数写起来更优雅吗?当然不是,还有一个很大的作用是与this的指向有关

ES5中,this指向的是函数被调用的对象;而ES6的箭头函数中,this指向的是函数被定义时所指向的对象。

简单来说,箭头函数的this,是不会变的,永远绑定在当前的环境下。

参考默认值

传统写法

1
2
3
function fn(param = 'hello'){
console.log)(param);
}

在ES6中定义方法时,我们可以给方法里的从参数加一个默认值( 缺省值):

  • 方法被调用时,如果没有给参数赋值,那就用默认值;
  • 方法被调用时,如果给参数复制了新的值,那就用新的值。

如下:

1
2
3
4
5
6
var fn2=(a,b=5)=>{
console.log('haha');
return a+b;
};
console.log(fn2(1));//第二个参数使用默认值5,输出结果:6
console.log(fn2(1,8));//输出结果:9

提醒1:默认值后面,不能再有没有默认值的变量。比如(a,b,c)这三个参数,如果我们给b设置了默认值,那么就一定要给c设置默认值。

提醒2

我们来看下面这段代码:

1
2
3
4
5
let x='smyh';
function fn(x,y=x){
console.log(x,y);
}
fn('vae');

注意第二行代码,我们给y赋值x,这里的x是括号里的第一个参数,并不是第一行代码里定义的x,打印结果为vae vae

如果我们将第一个参数修改一下,改成:

1
2
3
4
5
let x="smyh";
function fn(z,y=x){
console.log(z,y);
}
fn("vae");

此时打印结果为:vae smyh

扩展运算符

注意区分:

  • 扩展运算符的格式为:...
  • rest运算符的格式为...变量名

有了ES6,当我们在定义一个方法,但是不确定其参数个数时,我们可以用扩展运算符作为参数。

以前,我们在定义方法时,参数要确定个数,如下:(程序会报错)

1
2
3
4
5
6
7
function fn(a,b,c){
console.log(a);
console.log(b);
console.log(c);
console.log(d);
}
fn(1,2,3);

上述代码中,因为方法的参数是三个,但是使用的时候是用到了四个参数,所以会报错;

现在,我们有了扩展运算符,就不必担心报错的问题了。代码可以这样写:

1
2
3
4
5
6
7
function fn(...arg){//当不确定方法的参数时,可以使用扩展运算符
console.log(arg[0]);
console.log(arg[1]);
console.log(arg[2]);
console.log(arg[3]);
}
fn(1,2,3);//方法中定义了四个参数,但是只引用了三个参数,ES6中并不会报错。

上方代码中注意,arg参数之后,不能再加别的参数,否则会编译报错。

举例:数组赋值问题

我们来分析一段代码:(将数组arr1赋值给arr2)

1
2
3
4
5
6
7
8
9
10
let arr1=['www','smyhe','com'];
let arr2=arr1;//将arr1赋值给arr2,其实是让arr2指向arr1的内存地址
console.log('arr1:'+arr1);
console.log('arr2:'+arr2);
ocnsole.log('------------------');

arr2.push('你懂的');//往arr2里添加一部分内容
console.log('arr1:'+arr1);
console.log('arr2:'+arr2);

运行结果:

上方代码中,我们往arr2里添加le你懂的,却发现,arr1里面也有这个内容。原因是:let arr2=arr1其实是让arr2指向arr1的地址。也即是,二者指向的是同一个内存地址。

如果不想让arr1和arr2指向同一个内存地址,我们可以借助扩展运算符来做:

1
2
3
4
5
6
7
8
9
let arr1=['www','smyhvae','com'];
let arr2=[...arr1];//arr2会重新开辟内存地址
console.log('arr1:'+arr1);
console.log('arr2:'+arr2);
console.log('----------------');

arr2.push('你懂的');//往arr2里面添加一部分内容
console.log('arr1:'+arr1);
console.log('arr2:'+arr2);

我们明白了这个例子,就可以避免开发中很多业务逻辑上的bug。

rest运算符

rest在英文中指的是剩余部分(不是指休息)。

例:

1
2
3
4
function fn(first,second,...arg){
console.log(ar.length);
}
fn(0,1,2,3,4,5,6);//调用函数后,输出结果为5

上方代码的输出结果为5.调用fn()时,里面有七个参数,而arg指的是剩下的部分(因为除去了firstsecond).

从上面的例子可以看出,rest运算符适用于:知道前面的一部分参数的数量,丹斯对于后面的剩余的参数数量未知的情况。