ES6带来最重要的变化之一就是函数的许多新特性,废话很少说,咱们直接从最重要的变化开始提及。数组
ES6此次变化中最使人兴奋的就是引入了箭头(arrow)函数,js的开发者们已经等了过久了,以前的使用中,老是会被各类bind搞得晕头转向。如今有了箭头函数,这些烦恼将不复存在。浏览器
(params)=>{doSomething}安全
上面的形式使比较完整的。分为了函数参数、箭头、函数体几个部分。bash
若无函数参数,可使用下面的形式:
=>{doSomething}app
如果函数体只有一句的话,甚至能够省略包含函数体的大括号。函数
=> return a;ui
在ES6以前,咱们要是使用回调函数传参就要绑定函数的对象,不然会出错。例:this
//若是绑定,函数将没有执行环境
document.getElementsByName('button').onClick(this.callBack.bind(this));
function callBack(){ do somthing }
复制代码
而如今有了箭头函数,那这一切将变得垂手可得。spa
document.getElementsByName('button'.onClick(()=>{
do something...
}));
复制代码
这是由于箭头函数的this值直接绑定了外部函数的this值,而且这个this值是没法被改变的,虽然你可使用箭头函数调用call、apply、bind方法,可是他们依然没法改变函数的this绑定。这也是箭头函数最重要的特性之一,不须要咱们频繁的手动绑定函数的执行对象了。code
首先要说的一点是箭头函数没有arguments对象。可是能够访问外部函数的arguments对象。举个例子
function createArrowFunction(){
return ()=> arguments[0];
}
let test = createArrowFunction(1,2,3,4,5);
console.log(test); // 1
复制代码
其实也很好理解,既然箭头函数的this直接绑定了外部函数的this,那他就应该能够访问到外部函数的arguments对象。
箭头函数的参数一样支持传递默认参数(详细的会在后面讲)。咱们先来看看如何使用。
let sum = (param1 = 1, param2 = 1)=>{
console.log(param1 + param2);
}
sum(); // 2
复制代码
咱们上面也看到了一些箭头函数的特性,首先咱们来总结一下箭头函数的特色。
上面的特色致使了咱们与数组搭配在一块儿使用会相得益彰。
let arr = [1,2,3,4,5];
arr.forEach((element)=>{
console.log(element);
});
// 1
// 2
// 3
// 4
// 5
复制代码
能够说箭头函数是ES6中函数部分变化最大的改变。下面咱们将了解一下ES6中函数的其余变化。
在ES6以前咱们没法给函数形参添加默认值,可是咱们会用另外的形式去模拟这种行为。
function Person(name,age,sex){
this.name = name;
this.age = age || 18;
this.sex = sex || female;
}
// name: Nero, age:20, sex:female
new Person("Nero",20,female);
// name:Geodfrey,age:18,sex:female
new Person("Grodfrey");
复制代码
在上面的例子中咱们若是给函数的某个参数传递参数,那么将使用传递的参数,不然将使用 “||”后面的内容,这样就模拟了函数的默认参数。 上面的作法是一种很安全的作法,而且大多数JavaScript库与开发者们都采用这种方式,可是ES6依然添加进来了新的方式,为的是咱们更加方便的使用这种基础操做。
function Person(name,age = 20,sex = female){
this.name = name;
this.age = age;
this.sex = sex;
}
// name:"Grodfrey", age:20, sex:female
new Person("Grodfrey");
复制代码
其实很简单,就是才定义形参时加一个 “=”,后面跟上内容,简简单单的。还有一个比较重要的事情是,默认参数并非只支持传递原始值,也能够传递非原始值。例如函数表达式。这个传递什么类型的原始值取决于你的实际状况。
还有一个比较重要的特色就是,若是你主动传入undefined,函数也会调用默认值。
函数的默认参数也有临时死区,其实很容易理解,就是拥有默认值的参数不能在定义以前使用。咱们来看个例子就行了。
function sun(param1 = param2,param2 = 1){
return param1 + param2;
}
sum(1,2); // 2
sum(undefined,1); //抛出错误
复制代码
若是像下面的用法同样就会报错,简单的来讲就是在第一个参数要使用默认值(第二个参数)初始化时,可是第二个参数却尚未被初始化,这就产生了错误。
在ES6中为函数新增了元属性,其实这个属性就是为了让咱们区分函数的调用方式,若是使用new操做符调用函数时,元属性就会被赋值为new操做法的目标对象。若是是经过其余方式调用的,那这个属性的值就为undefined。
function Person(name){
if(new.target !== "undefined"){
this.name = name;
}else{
console.log("请使用new操做符");
}
}
let person = new Person("nero");
Person.call(person,"Grodfery"); //请使用new操做符
复制代码
这样的化咱们就能够明确划分函数的做用了。一些构造函数能够防止被其余类型的对象调用,产生一些错误。
new.target属性只能在函数内部使用,若是在函数外部使用,将会抛出错误。
在ES6中引入了块级函数,此次是官方引入的,虽然以前有一些浏览器也都是实现了块级函数,可是各不相同,此次ES6规定了块级函数的语法。
块级函数的语法很简单,其实你彻底能够看成一个let定义的变量来使用,惟一的一个区别就是:块级函数会进行变量提高。
if(true){
console.log(typeOf doSomething); // Function
function doSomething(){}
}
console.log(typeof doSomething); // undefined
复制代码
当块级函数一旦离开相应的代码块,那么这个函数将被删除。
不定参数是运行你传入数量不定的参数进入函数,在函数中会被整合成数组。 而展开运算符与之相反,是将一个数组打散,一个一个的传入数组。
function Person(name,age,sex,...others){
this.name = name;
this.age = age;
this.sex = sex;
for(let i = 0;i<others.length;i++){
console.log(others[i]);
}
}
复制代码
咱们能够在传入固定参数以后传入任意多个参数。,都会被存储在函数内部的不定参数同名的数组中。
不定参数有两个须要注意的地方
//这种使用方式是有错误的。
// Uncaught SyntaxError: Rest parameter must be last formal parameter
function doSomething(param1,...objs,param2){}
复制代码
//这种操做也是不容许的,
let obj = {
set name(..key){}
}
复制代码
不定参数中的值也会在arguments中,也就是说,即便不实用不定参数,继续使用原来的arguments对象也是彻底没问题的。
展开运算符的用法就比较简单了。
let value = [1,2,3,4,5,6,7,8,9];
console.log(Math.max(...value));
复制代码
展开运算符极大的方便了咱们,咱们不须要再写一个循环或者经过其余方式将一个数组的变量传递到函数中去,只须要在数组前面使用 “...”符号,那么就会将他们打散传递给函数。
此次探讨的是ES6中有关函数的变更,有些内容我省略掉了,例如name属性,我只列举了一些我以为会比较经常使用的。这都是基于我在工做中的认识,若是您有一些更好的想法或者是本篇文章某处错误,你均可以在下面留言给我!!!