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]
複製代碼

摘自:阮一峯

相關文章
相關標籤/搜索