ES6函数第三篇:函数篇(新增API与箭头函数)
1.新增API——new.target
眾所周知,js中構造函數(shù)需使用new來調(diào)用,但是即使不使用new關鍵字,也可以調(diào)用構造函數(shù),如【例1-1】,為了解決這一問題,js的解決方式為使用instanceof查看原型上是否有該構造函數(shù),如【例1-2】,到了es6提供了一個特殊的API,可以使用該API在函數(shù)內(nèi)部,判斷該函數(shù)是否使用new來調(diào)用,如【例1-3】
【例1-1】構造函數(shù)的兩種調(diào)用方式
function Person(firstName, lastName) {this.firstName = firstName;this.lastName = lastName;this.fullName = `${firstName}${lastName}`;//純碎是為了讓p1有返回值return `${this.firstName} ${this.lastName} ${this.fullName}` } const p1 = Person("J", "wh"); const p2 = new Person('T','hs'); console.log(p1); console.log(p2);【結果】?
圖1-1?【例1-2】之前的解決方式
function Person(firstName, lastName) {if (!(this instanceof Person)) {throw new Error('該函數(shù)沒有使用new來調(diào)用')}this.firstName = firstName;this.lastName = lastName;this.fullName = `${firstName}${lastName}`; } const p2 = new Person('T','hs'); console.log(p2); const p1 = Person("J", "wh"); console.log(p1);【結果】
圖1-2-1細心的讀者可能已經(jīng)發(fā)現(xiàn)了,這種間接的方法可能導致人為改變this指向后,使得原型鏈上有構造函數(shù),即該判斷是可以避開的,存在bug,如下例
const p2 = new Person('T', 'hs'); console.log(p2); const p3 = Person.call(p2, 'J', 'wh') console.log(p3)【結果】
圖1-2-2因此,es6提供了新的API —— new.target去直接解決這一問題,該表達式的用法是:當沒有使用new調(diào)用函數(shù)時,返回undefined;若使用了new來調(diào)用,則得到new關鍵字后面的函數(shù)本身
【例1-3】
function Person(firstName, lastName) {if (new.target === undefined) {throw new Error('該函數(shù)沒有使用new來調(diào)用')}this.firstName = firstName;this.lastName = lastName;this.fullName = `${firstName}${lastName}`; } const p2 = new Person('T', 'hs'); console.log(p2); const p3 = Person.call(p2, 'J', 'wh') console.log(p3); 圖1-32.箭頭函數(shù)
(1) this指向
- 通過對象調(diào)用函數(shù),this指向?qū)ο?/li>
- 直接調(diào)用函數(shù),this指向全局對象
- 如果通過new調(diào)用函數(shù),this指向新創(chuàng)建的對象
- 如果apply,call,bind調(diào)用函數(shù),this指向指定的數(shù)據(jù)
- 如果是dom時間函數(shù),this指向事件源
下面給個定時器的例子
【例2-1-1】
const obj = {count: 0,start: function () {setInterval(function () {this.count++;console.log(this.count);}, 1000)} } obj.start();【結果】本來代碼想實現(xiàn)的效果是, 沒隔一秒count加1,但是由于定時器的this指向window,因此打印結果為
圖2-1-1之前的解決方式是,在start方法中保存this指向,如下,則可以解決該問題
const obj = {count: 0,start: function () {//保存thisconst self = this;setInterval(function () {self.count++;console.log(self.count);}, 1000)} } obj.start();(2)箭頭函數(shù)
es6在解決上述問題時引入了箭頭函數(shù)。箭頭函數(shù)是一個函數(shù)表達式,理論上,任何使用函數(shù)表達式的場景都可以使用箭頭函數(shù)
語法規(guī)則
- 完整語法:(參數(shù)1, 參數(shù)2,...) => {函數(shù)體}
- 如果只有一個參數(shù),可以省略小括號:參數(shù)=>{函數(shù)體}【例2-2-2】
- 如果箭頭函數(shù)只有一條返回語句,可以省略大括號,和return關鍵字:參數(shù)=>返回值
箭頭函數(shù)的特點
- 箭頭函數(shù)中,不存在this,arguments,new.target,如果使用了,則是函數(shù)外層的對應的this,arguments,new.target
- 箭頭函數(shù)沒有原型
- 箭頭函數(shù)不能作用構造函數(shù)使用
應用場景
- 臨時性使用的函數(shù),并不會且不可以調(diào)用它,如:事件處理函數(shù),異步處理函數(shù),其他臨時性的函數(shù)
- 為了綁定外層this的函數(shù)
- 在不影響其他代碼的情況下,保持代碼的簡潔,最常見的,數(shù)組方法中的回調(diào)函數(shù)
【例2-2-1】
const obj = {count: 0,start: function () {setInterval(() =>{this.count++;console.log(this.count);}, 1000)} } obj.start();【例2-2-2】
const print = num => {console.log('打印:', num); } print(2);【例2-2-3】
const sum = (a,b)=> ({a:a,b:b,sum:a+b }); console.log(sum(3,5));【例2-2-4】
const numbers = [3, 7, 4, 8, 9]; const result = numbers.filter(num => num % 2 !== 0).map(num => num * 2).reduce((a, b) => a + b) console.log(result);?
總結
以上是生活随笔為你收集整理的ES6函数第三篇:函数篇(新增API与箭头函数)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ES6函数第二篇:剩余参数与展开运算符的
- 下一篇: ES6对象(1):新增语法与API