對於函數而言,常常會用到參數,關於參數的默認值一般寫在函數體內。函數express
函數參數是爲從左到右解析,沒有默認值會被解析爲undefined數組
ES5默認參數寫法,過於臃腫,且重複app
function f (x, y, z) { if (y === undefined) y = 7; if (z === undefined) z = 42; return x + y + z; }; f(1) === 50;
ES6默認參數寫法,有默認值參數通常寫在無默認值參數以後。(即便不按順序寫,如今也不報錯,)函數
function f (x, y = 7, z = 42) { return x + y + z } console.log(f(1, undefined, 43))// 51 //從左向右解析,想讓某個參數使用默認值,就使用undefined來賦值 function f (x, y = 7, z = 42, h = 5) { return x + y + z+ h } console.log(f(1, undefined, 43))// 56 //從左向右解析,若是有剩餘參數未傳入值,也按默認值處理
ES6中參數能夠用於後面的參數的邏輯計算進行賦值this
function f (x, y = 7, z = x + y) { return z * 0.5 } console.log(f(1, 7))// 4
在函數體內的函數聲明不能引用內部的默認參數,會報錯。prototype
// Doesn't work! Throws ReferenceError. function f(a = go()) { function go() { return ':P'; } }
還能夠經過解構賦值爲參數賦值指針
function f([x, y] = [1, 2], {z: z} = {z: 3}) { return x + y + z; } f(); // 6
判斷函數體內有幾個參數rest
ES5 中能夠在函數體內使用 arguments 來判斷code
function test (a, b = 1, c) { console.log(arguments.length) } test('a', 'b')//2
ES6 中不能再使用 arguments 來判斷了,但能夠藉助 Function.length 來判斷,可是隻能統計一個默認參數以前的變量數對象
function test (a, b = 1, c) { console.log(test.length) } test('a', 'b')// 1
ES5中,不肯定剩餘參數有多少個,或不須要知道剩餘參數都是什麼玩意的狀況下進行邏輯運算
好比求和運算
function sum () { let num = 0 Array.prototype.forEach.call(arguments, function (item) { num += item * 1 }) return num } console.log(sum(1, 2, 3))// 6 console.log(sum(1, 2, 3, 4))// 10
ES6中arguments很差使,提供了新的方式.即rest 參數。
rest 參數以後不能再有其餘參數,且函數的 length 屬性,不包括rest參數
function sum (...nums) { let num = 0 nums.forEach(function (item) { num += item * 1 }) return num } console.log(sum(1, 2, 3))// 6 console.log(sum(1, 2, 3, 4))// 10 //...nums(Rest Paramete)表明參數的集合,而且是一個數組
Rest Paramete也能夠和其餘參數一塊兒來使用
function sum (base, ...nums) { let num = base nums.forEach(function (item) { num += item * 1 }) return num } console.log(sum(30, 1, 2, 3))// 36 console.log(sum(30, 1, 2, 3, 4))// 40
Rest參數和arguments對象的區別:
1.rest參數只包括那些沒有給出名稱的參數,arguments包含全部參數
2.arguments 對象不是真正的數組,而rest 參數是數組實例,能夠直接應用sort, map, forEach, pop等方法
3.arguments 對象擁有一些本身額外的功能
很方便易懂的語法,把固定的數組內容「打散」到對應的參數
function sum (x = 1, y = 2, z = 3) { return x + y + z } console.log(sum(...[4]))// 9 console.log(sum(...[4, 5]))// 12 console.log(sum(...[4, 5, 6]))// 15
ES5函數必須使用function。而箭頭函數不須要,而且使函數簡短。
let hello = () => { console.log('say hello') }
箭頭函數的語法示例
(param1, param2, …, paramN) => { statements } (param1, param2, …, paramN) => expression //至關於:(param1, param2, …, paramN) =>{ return expression; } // 當只有一個參數時,圓括號是可選的: (singleParam) => { statements } singleParam => { statements } // 沒有參數的函數應該寫成一對圓括號。 () => { statements } //加括號的函數體返回對象字面量表達式: params => ({foo: bar}) //支持剩餘參數和默認參數 (param1, param2, ...rest) => { statements } (param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } //一樣支持參數列表解構 let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; f(); // 6
箭頭函數不會建立本身的this它只會從本身的做用域鏈的上一層繼承this
let test = { name: 'test', say: () => { console.log(this.name, this) } } console.log(test.say())// undefined //this 的指向也就是 test 外層的所指向的 window,而 window 沒有 name 屬性,因此結果是 undefined
因爲 箭頭函數沒有本身的this指針,經過 call()或 apply() 方法調用一個函數時,只能傳遞參數(不能綁定this),他們的第一個參數會被忽略
var adder = { base : 1, add : function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // 輸出 2 console.log(adder.addThruCall(1)); // 仍然輸出 2