默認參數:
1. 在 ES5 語法中,為函數形參指定默認值的寫法:
寫法一: function foo (bar) { bar = bar || 'abc'; console.log(bar) } foo('xyz') 寫法二: function foo (bar) { if (typeof bar === 'undefined') { bar = 'abc'; } console.log(bar) } foo('xyz');
2. 使用 ES6 的語法為函數形參指定默認值
function post (url, data = {}, timeout = 5 * 1000) { console.log(arguments) console.log(url, data, timeout) } // post('xyz', {uname: 'zhangsan', upass: '123'}, 3000); post('xyz', null, 3000);
注意事項:
1> 除了為形參直接指定默認值以外,形參的默認值還可以是表達式,例如,timeout = 5 * 1000
2> 在預編譯階段,形參表達式不會執行,只有在調用函數,並且沒有為形參傳遞實參的情況下才執行
不定參數:
使用剩余操作符接收剩余的實參,這些實參會被保存到一個不定參數(args)中
function foo (...args) { return args.reduce(function (previousValue, currentValue) { console.log(previousValue, currentValue) return previousValue += currentValue; }) } // 將上面的函數改成箭頭函數的形式 var foo = (...args) => args.reduce((a, b) =>a += b) console.log(foo(1, 32, 34, 5, 6))
箭頭函數:
// 1. 形式一: var foo = function () { return 'Hello World!'; }; // 如果形參數量為 0,則必須加上小括號。箭頭后面的表達式的結果會被作為函數的返回值。 var foo = () => { return 'Hello World!'; } // 2. 形式二: var foo = function (greeting) { return greeting; } // 如果形參的數量為 1,則可以省略小括號。 var foo = greeting => { return greeting; } // 3. 形式三: var foo = function (firstName, lastName) { return firstName + ' · ' + lastName; } // 如果形參數量大於 1,則不能省略小括號。 var foo = (firstName, lastName) => { return firstName + ' · ' + lastName; } // 4. 形式四: var foo = function (a, b) { return a > b ? a : b; } // 如果函數的執行體比較簡單(直接量或表達式),可以省略大括號,箭頭后面的直接量或表達式會被自動作為返回值。 var foo = (a, b) => a > b ? a : b; // 5. 形式五: var foo = function (a, b) { let max = a; if (b > a) { max = b; } return max; } // 如果函數的執行體比較復雜,則不能省略大括號。 var foo = (a, b) => { let max = a; if (b > a) { max = b; } return max; } console.log(foo('趙四', '尼古拉斯'))
箭頭函數沒有this指定:
// 普通函數作用域中的 this 已經被綁定成 window 對象,因此當我們放問 this 時,直接在當前作用域下就能訪問的到。 var foo = function () { console.log(this) return 'Hello World!'; }; // 箭頭函數的作用域中沒有綁定 this,因此,當我們訪問 this 時,會去上一層作用域中查找 this。 var bar = () => { console.log(this) return 'Hello World!'; }; // 示例,由於 sayName 箭頭函數中沒有綁定 this,因此我們訪問 this 時,會去全局作用域中查找。 // 查找的結果是 this 指向 window,因此輸出的 name 的值是 '豬豬俠' var name = '豬豬俠'; var obj = { name: '煎餅俠', sayName: function () { // this = obj return this.name; } }; console.log(obj.sayName())
箭頭函數沒有arguments綁定:
// 普通函數 var foo = function (greeting) { console.log(arguments) return greeting; }; // 箭頭函數中沒有綁定 arguments 對象,因此下面的輸入語句會報錯:arguments is not defined var bar = (greeting) => { console.log(arguments) return greeting; }; console.log(foo('Hello World!')) console.log(bar('你好世界!'))
箭頭函數中不能手動綁定this:
// this 指向的對象 var obj = { fullName: '沃爾瑪' }; // 1. 普通函數,可以使用 call() 方法改變函數中 this 的綁定 var foo = function (greeting) { return this.fullName + '說:' + greeting; }; console.log(foo.call(obj, 'Hello World!')) // 2. 箭頭函數,不能使用 call() 方法改變函數中 this 的綁定,箭頭函數中不能綁定 this。 var bar = (greeting) => { return this.fullName + '說:' + greeting; }; // 下面的代碼不會報錯,但是也不起作用 console.log(bar.call(obj, '你好世界!'))
函數--new.target:
// 1. ECMAScript 5 中判斷構造函數是否通過 new 關鍵字調用的寫法 function Person (fullName) { if (this instanceof Person) { this.fullName = fullName; } else { return new Person(fullName); } } let student = Person('八戒') // 2. ECMASript 6 引入一個 new.target 屬性,當我們使用 new 操作符調用構造函數時,new.target 屬性的值為構造函數,否則為 undefined function Person (fullName) { if (typeof new.target !== 'undefined') { this.fullName = fullName; } else { throw new Error('必須通過 new 關鍵字來調用 Person。'); } } let student = new Person('八戒'); console.log(student) // 3. 除此之外,還可以檢查 new.target 是否被某個特定構造函數所有調用。 // 例如,Person 構造函數中的 new.target 屬性的值被限定為 Person function Person (fullName, age) { if (typeof new.target === Person) { this.fullName = fullName; this.age = age; } else { throw new Error('必須通過 new 關鍵字來調用 Person。'); } } function Dog (fullName, age) { Person.call(this, fullName, age) } let dog = new Dog('HeHe', 3) console.log(dog) // 4. 不能在函數外部使用 new.target,否則會報錯 function Person () { console.log(new.target) } // 下面代碼會拋出錯誤:new.target expression is not allowed here console.log(new.target) let student = new Person('悟凈')