ES6 函数相关

1.1函数参数的默认值

1.1.1用法

ES6容许为函数参数设置默认值,直接写在参数定义的后面。es6

// ES5
function log(x, y){
  x = x || 'hello';
  console.log(x,' ',y);
}
log(false,'world'); // hello world

//ES6
function log(x = 'hello', y){
  console.log(x,' ',y);
}
log(false,'world'); // false world
复制代码

ES6写法的好处:简洁、代码可读性高、利于代码优化数组

注意:参数变量是默认声明,不能用let或const重复声明;不能有同名参数;参数默认值不传值,每次从新计算默认值表达式的值。bash

// 惰性求值
let x = 99;
function foo(p = x + 1) {
  console.log(p);
}

foo() // 100

x = 100;
foo() // 101
复制代码

1.1.2结合解构赋值使用

function foo({x, y = 5} = {}) {
  console.log(x, y);
}

foo() // undefined 5
// 若是函数参数不默认为空对象,foo()会报错
复制代码

1.1.3参数默认值位置

注意参数默认值的位置,最好写在最后面,容易看出来。若是非尾部参数设置默认值,这个参数实际上没法省略。函数

// 例一
function f(x = 1, y) {
  return [x, y];
}

f() // [1, undefined]
f(2) // [2, undefined])
f(, 1) // 报错
f(undefined, 1) // [1, 1]

// 例二
function f(x, y = 5, z) {
  return [x, y, z];
}

f() // [undefined, 5, undefined]
f(1) // [1, 5, undefined]
f(1, ,2) // 报错
f(1, undefined, 2) // [1, 5, 2]
复制代码

1.1.4函数length属性

length属性的含义:该函数预期传入的参数个数。某个参数指定默认值之后,预期传入的参数不包括这个参数。优化

因此指定默认值后,length属性会失真。若是设置默认值的参数不是尾参数,length属性不计后面的参数。ui

(function (a) {}).length // 1
(function (a = 5) {}).length // 0
(function (a, b, c = 5) {}).length // 2
(function(...args) {}).length // 0
(function (a = 0, b, c) {}).length // 0
(function (a, b = 1, c) {}).length // 1
复制代码

1.1.5做用域

一旦设置了参数的默认值,函数进行声明初始化时,参数会造成一个单独的做用域(context)。等到初始化结束,这个做用域就会消失。这种语法行为,在不设置参数默认值时,是不会出现的。this

let x = 1;

function f(x, y = x) {
  console.log(y);
}

f(2) // 2

let x = 1;

function f(y = x) {
  let x = 2;
  console.log(y);
}

f() // 1
复制代码

1.2rest参数

rest参数形式为...变量名(数组),用来获取多于参数,能够替代arguments对象,写法更简洁spa

// arguments变量的写法
function sortNumbers() {
  return Array.prototype.slice.call(arguments).sort();
}

// rest参数的写法
const sortNumbers = (...numbers) => numbers.sort();
复制代码

1.3name属性

函数的name属性,返回该函数的函数名。若是将一个匿名函数赋值给一个变量,ES6会返回实际的函数名,ES5返回空字符串。其余状况看代码。prototype

var f = function () {};

// ES5
f.name // ""

// ES6
f.name // "f"

const bar = function baz() {};

// ES5
bar.name // "baz"

// ES6
bar.name // "baz"

(new Function).name // "anonymous"

function foo() {};
foo.bind({}).name // "bound foo"

(function(){}).bind({}).name // "bound "
复制代码

箭头函数(重点)

用法

ES6容许使用箭头定义函数,若是箭头函数不须要参数或须要多个参数,使用圆括号表明参数部分,若是只有一个参数,能够省略圆括号;若是代码块多于一条语句,用大括号括起来,并使用return语句返回,若是只有代码块只有一条语句,能够省略大括号和return。rest

var f = v => v;
// 等同于
var f = function (v) {
  return v;
};

var f = () => 5;
// 等同于
var f = function () { return 5 };

var sum = (num1, num2) => num1 + num2;
// 等同于
var sum = function(num1, num2) {
  return num1 + num2;
};
复制代码

因为大括号被解释为代码块,因此若是箭头函数直接返回一个对象,必须在对象外面加上括号,不然会报错。

// 报错
let getTempItem = id => { id: id, name: "Temp" };

// 不报错
let getTempItem = id => ({ id: id, name: "Temp" });
复制代码

箭头函数与变量解构结合

let person = {
  first: 'hello',
  last: 'world',
}
const full = ({first,last}) => first + ' ' + last;
console.log(full(person)); // hello world
复制代码

简化回调函数

// 正常函数写法
[1,2,3].map(function (x) {
  return x * x;
});

// 箭头函数写法
[1,2,3].map(x => x * x);
复制代码

能够与rest参数结合

const numbers = (...nums) => nums;

numbers(1, 2, 3, 4, 5)
// [1,2,3,4,5]
复制代码

注意点

  1. 函数体内的this对象就是定义时所在的对象,而不是使用时所在的对象。箭头函数的this对象不会发生改变。
  2. 不能够看成构造函数。箭头函数没有constructor方法,因此不能够看成构造函数,也不可使用new命令。
  3. 不支持arguments对象,该对象在函数体内不存在,能够用rest参数来实现arguments对象的效果。
  4. 不可使用yield命名,不能用做generator函数。
// this指向问题
function foo1(){
  setTimeout(()=>{
    console.log('箭头函数id:',this.id);
  },1000);
}
function foo2(){
  setTimeout(function(){
    console.log('非箭头函数id',this.id);
  },1000);
}
var id = 21;
foo1.call({ id: 42 }); // 42
foo2.call({ id: 42 }); // 21
复制代码

不适用场合

  1. 定义对象的方法,该方法内部包括this
const cat = {
  lives: 9,
  jumps: () => {
    this.lives--;
  }
}
cat.jumps();
console.log(cat.lives); // 9
复制代码

并无达到预期效果

  1. 须要动态this的时候
const button = document.querySelector('button');
button.addEventListener('click', () => {  
    this.textContent = 'Loading...';
});
// this 并非指向预期的 button 元素,而是 window
复制代码
  1. 函数体很复杂,或者内部有大量读写,不单纯为了计算值,要用普通函数,能够提升代码可读性。

嵌套的箭头函数

let insert = (value) => ({into: (array) => ({after: (afterValue) => {
  array.splice(array.indexOf(afterValue) + 1, 0, value);
  return array;
}})});

insert(2).into([1, 3]).after(1); //[1, 2, 3]
复制代码

摘自:阮一峰

相关文章
相关标签/搜索