ES6-函数优化&箭头函数(使用较多)

以下是对函数,不定参数,箭头函数的学习


函数参数的默认值

1
2
3
4
5
6
7
8
9
10
11
12
13
//在ES6以前,我们无法给一个函数参数设置默认值,只能采用变通写法;
function add(a, b) {
//判断是否为空,为空就给默认值;
b = b || 1;
return a + b;
}
//传一个参数
console.log(add(10));
//现在可以这么写,直接给参数写上默认值,没传给会自动使用默认值
function add2(a, b = 1) {
return a + b;
}
console.log(add2(20));

注意点:使用函数默认参数时,不允许有同名参数。

1
2
3
4
5
6
7
8
9
10
// 不报错
function fn(name,name){
console.log(name);
}

// 报错
//SyntaxError: Duplicate parameter name not allowed in this context
function fn(name,name,age=17){
console.log(name+","+age);
}

只有在未传递参数,或者参数为 undefined 时,才会使用默认参数,null 值被认为是有效的值传递。

1
2
3
4
function fn(name,age=17){
console.log(name+","+age);
}
fn("Amy",null); // Amy,null

不定参数

不定参数用来表示不确定参数个数,形如,…变量名,由…加上一个具名参数标识符组成。具名参数只能放在参数组的最后,并且有且只有一个不定参数。

基本用法

1
2
3
4
5
function f(...values){
console.log(values.length);
}
f(1,2); //2
f(1,2,3,4); //4

箭头函数(使用较多)

1
2
3
4
5
6
7
8
9
10
11
12
13
      //以前声明一个方法
// var print=function(obj){
// console.log(obj);
// }
var print = (obj) => console.log(obj);
print('hello');//hello

var f = v => v;
//等价于
var f = function(a){
return a;
}
f(1); //1

当箭头函数没有参数或者有多个参数,要用 () 括起来。

1
2
var f = (a,b) => a+b;
f(6,2); //8

当箭头函数函数体有多行语句,用 {} 包裹起来,表示代码块,当只有一行语句,并且需要返回结果时,可以省略 {} , 结果会自动返回。

1
2
3
4
5
var f = (a,b) => {
let result = a+b;
return result;
}
f(6,2); // 8

当箭头函数要返回对象的时候,为了区分于代码块,要用 () 将对象包裹起来

1
2
3
4
5
6
7
// 报错
var f = (id,name) => {id: id, name: name};
f(6,2); // SyntaxError: Unexpected token :

// 不报错
var f = (id,name) => ({id: id, name: name});
f(6,2); // {id: 6, name: 2}

注意点:没有 this、super、arguments 和 new.target 绑定。
箭头函数体中的 this 对象,是定义函数时的对象,而不是使用函数时的对象。
不可以作为构造函数,也就是不能使用 new 命令,否则会报错

  • 箭头函数+解构
1
2
3
4
5
6
7
8
9
10
11
12
const person = {
name: 'jack',
age: 21,
language: ['java', 'js', 'css'],
};

function hello(person) {
console.log('hello', person.name);
}
//箭头函数+解构
var hello2 = ({ name }) => console.log('hello', name);
hello2(person);

箭头函数和普通函数的区别

本篇我们重点比较一下箭头函数与普通函数。
主要区别包括:

没有 this

箭头函数没有 this,所以需要通过查找作用域链来确定 this 的值。
这就意味着如果箭头函数被非箭头函数包含,this 绑定的就是最近一层非箭头函数的 this。

1.箭头函数this为父作用域的this,不是调用时的this

this
箭头函数的this永远指向其父作用域,任何方法都改变不了,包括call,apply,bind。

普通函数的this指向调用它的那个对象。

上例中,init为箭头函数,其内部的this为全局window,onclick的this也就是init函数的this,也是window,得到的this.name就为undefined。

没有 arguments

箭头函数没有自己的 arguments 对象,这不一定是件坏事,因为箭头函数可以访问外围函数的 arguments 对象:
那如果我们就是要访问箭头函数的参数呢?
你可以通过命名参数或者 rest 参数的形式访问参数:
let nums = (…nums) => nums;

不能通过 new 关键字调用

JavaScript 函数有两个内部方法:[[Call]] 和 [[Construct]]。

当通过 new 调用函数时,执行 [[Construct]] 方法,创建一个实例对象,然后再执行函数体,将 this 绑定到实例上。

当直接调用的时候,执行 [[Call]] 方法,直接执行函数体。

箭头函数并没有 [[Construct]] 方法,不能被用作构造函数,如果通过 new 的方式调用,会报错。

var Foo = () => {};
var foo = new Foo(); // TypeError: Foo is not a constructor

没有 new.target

因为不能使用 new 调用,所以也没有 new.target 值。

关于 new.target,可以参考 es6.ruanyifeng.com/#docs/class…

没有原型

由于不能使用 new 调用箭头函数,所以也没有构建原型的需求,于是箭头函数也不存在 prototype 这个属性。

var Foo = () => {};
console.log(Foo.prototype); // undefined

没有 super

连原型都没有,自然也不能通过 super 来访问原型的属性,所以箭头函数也是没有 super 的,不过跟 this、arguments、new.target 一样,这些值由外围最近一层非箭头函数决定。

箭头函数表达式的语法比函数表达式更短,并且不绑定自己的this,arguments,super或 new.target。这些函数表达式最适合用于非方法函数(non-method functions),并且它们不能用作构造函数

参考文章