摘要:錯誤的寫法錯誤的寫法中的構(gòu)造函數(shù)新增了支持默認(rèn)參數(shù)和不定參數(shù)。箭頭函數(shù)的簡單理解箭頭函數(shù)的左邊表示輸入的參數(shù),右邊表示輸出的結(jié)果。但是有了尾調(diào)用優(yōu)化之后,遞歸函數(shù)的性能有了提升。
作為前端切圖仔,越發(fā)覺得自己離不開函數(shù)了。
說到JavaScript函數(shù),腦子里都是匿名函數(shù)、普通函數(shù)、閉包函數(shù)、構(gòu)造函數(shù)......然后還能說出一大堆函數(shù)的概念。如果你達(dá)到這個水平,那么函數(shù)對你來說沒有難度,是一個前端老鳥了。
當(dāng)我閉上眼睛,不看鍵盤,手指在鍵盤上敲擊出一個排序函數(shù)的時候,我在想,還是回顧一下函數(shù)的基本知識才有意思。
函數(shù)的默認(rèn)參數(shù)在ES5中,我們給函數(shù)傳參數(shù),然后在函數(shù)體內(nèi)設(shè)置默認(rèn)值,如下面這種方式。
function a(num, callback) { num = num || 6 callback = callback || function (data) {console.log("ES5: ", data)} callback(num * num) } a() //ES5: 36,不傳參輸出默認(rèn)值 //你還可以這樣使用callback a(10, function(data) { console.log(data * 10) // 1000, 傳參輸出新數(shù)值 })
而在ES6中,我們使用新的默認(rèn)值寫法。
function a(num = 6, callback = function (data) {console.log("ES6: ", data)}) { callback(num * num) } a() //ES6: 36, 不傳參輸出默認(rèn)值 a(10, function(data) { console.log(data * 10) // 1000,傳參輸出新數(shù)值 })
使用ES6的默認(rèn)值寫法可以讓函數(shù)體內(nèi)部的代碼更加簡潔優(yōu)雅
默認(rèn)值對arguments對象的影響
我們先要了解arguments對象是什么?準(zhǔn)確一點來說它是一個類數(shù)組對象,它存在函數(shù)內(nèi)部,它將當(dāng)前函數(shù)的所有參數(shù)組成了一個類數(shù)組對象。
function a(num, b){ console.log(arguments) // {"0": 6, "1": 10} console.log(arguments.length) // 2 } a(6, 10)
上面的輸出結(jié)果看起來很正常,那么,如果我們加上參數(shù)默認(rèn)值會怎樣呢?
function a(num = 1, b = 1){
console.log(arguments)
}
a() // {} 默認(rèn)值不能被arguments識別。
a(6, 10) // {"0":6,"1":10}
下面我們看一下修改參數(shù)默認(rèn)值對arguments的影響。
1、在ES5的非嚴(yán)格模式下,一開始輸入的參數(shù)是1,那么可以獲取到arguments[0](表示第一個參數(shù))全等于num,修改num = 2之后,arguments[0]也能更新到2。
function a(num){ console.log(num === arguments[0]) //true num = 2 //修改參數(shù)默認(rèn)值 console.log(num === arguments[0]) //true } a(1)
2、在ES5的非嚴(yán)格模式下,arguments就不能在函數(shù)內(nèi)修改默認(rèn)值后跟隨著跟新了。
"use strict"; //嚴(yán)格模式 function a(num) { console.log(num === arguments[0]); // true num = 2; console.log(num === arguments[0]); // false } a(1);
在ES6環(huán)境下,默認(rèn)值對arguments的影響和ES5嚴(yán)格模式是同樣的標(biāo)準(zhǔn)。
默認(rèn)參數(shù)表達(dá)式
參數(shù)不僅可以設(shè)置默認(rèn)值為字符串,數(shù)字,數(shù)組或者對象,還可以是一個函數(shù)。
function add() { return 10 } function a(num = add()){ console.log(num) } a() // 10
默認(rèn)參數(shù)的臨時死區(qū)
第一章我們提到了let和const什么變量的臨時死區(qū)(TDZ),默認(rèn)參數(shù)既然是參數(shù),那么也同樣有臨時死區(qū),函數(shù)的作用域是獨(dú)立的,a函數(shù)不能共享b函數(shù)的作用域參數(shù)。
//這是個默認(rèn)參數(shù)臨時死區(qū)的例子,當(dāng)初始化a時,b還沒有聲明,所以第一個參數(shù)對b來說就是臨時死區(qū)。 function add(a = b, b){ console.log(a + b) } add(undefined, 2) // b is not define無命名參數(shù)
上面說的參數(shù)都是命名參數(shù),而無命名參數(shù)也是函數(shù)傳參時經(jīng)常用到的。當(dāng)傳入的參數(shù)是一個對象,不是一個具體的參數(shù)名,則是無命名參數(shù)。
function add(object){ console.log(object.a + object.b) } let obj = { a: 1, b: 2 } add(obj) // 3
不定參數(shù)的使用:使用...(展開運(yùn)算符)的參數(shù)就是不定參數(shù),它表示一個數(shù)組。
function add(...arr){ console.log(a + b) } let a = 1,b = 2 add(a, b) // 3
不定參數(shù)的使用限制:必須放在所有參數(shù)的末尾,不能用于對象字面量setter中。
//錯誤的寫法1 function add(...arr, c){ console.log(a + b) } let a = 1,b = 2,c = 3 add(a, b, c) //錯誤的寫法2 let obj = { set add(...arr) { } }
ES6中的構(gòu)造函數(shù)Function新增了支持默認(rèn)參數(shù)和不定參數(shù)。
展開運(yùn)算符(...)展開運(yùn)算符的作用是解構(gòu)數(shù)組,然后將每個數(shù)組元素作為函數(shù)參數(shù)。
有了展開運(yùn)算符,我們操作數(shù)組的時候,就可以不再使用apply來指定上下文環(huán)境了。
//ES5的寫法 let arr = [10, 20, 50, 40, 30] let a = Math.max.apply(null, arr) console.log(a) // 50 //ES6的寫法 let arr = [10, 20, 50, 40, 30] let a = Math.max(...arr) console.log(a) // 50塊級函數(shù)
嚴(yán)格模式下:在ES6中,你可以在塊級作用域內(nèi)聲明函數(shù),該函數(shù)的作用域只限于當(dāng)前塊,不能在塊的外部訪問。
"use strict"; if(true) { const a = function(){ } }
非嚴(yán)格模式:即使在ES6中,非嚴(yán)格模式下的塊級函數(shù),他的作用域也會被提升到父級函數(shù)的頂部。所以大家寫代碼盡量使用嚴(yán)格模式,避免這些奇葩情況。
箭頭函數(shù)(=>)如果看到你這里,你發(fā)現(xiàn)你還沒有在項目中使用過箭頭函數(shù),沒關(guān)系,你并不low,而是學(xué)習(xí)不夠努力。
const arr = [5, 10] const s = arr.reduce((sum, item) => sum + item) console.log(s) // 15
箭頭函數(shù)和普通函數(shù)的區(qū)別是:
1、箭頭函數(shù)沒有this,函數(shù)內(nèi)部的this來自于父級最近的非箭頭函數(shù),并且不能改變this的指向。
2、箭頭函數(shù)沒有super
3、箭頭函數(shù)沒有arguments
4、箭頭函數(shù)沒有new.target綁定。
5、不能使用new
6、沒有原型
7、不支持重復(fù)的命名參數(shù)。
箭頭函數(shù)的簡單理解
1、箭頭函數(shù)的左邊表示輸入的參數(shù),右邊表示輸出的結(jié)果。
const s = a => a console.log(s(2)) // 2
2、箭頭函數(shù)中,最重要的this報錯將不再成為你每天都擔(dān)心的bug。
3、箭頭函數(shù)還可以輸出對象,在react的action中就推薦這種寫法。
const action = (type, a) => ({ type: "TYPE", a })
4、支持立即執(zhí)行函數(shù)表達(dá)式寫法
const test = ((id) => { return { getId() { console.log(id) } } })(18) test.getId() // 18
5、箭頭函數(shù)給數(shù)組排序
const arr = [10, 50, 30, 40, 20] const s = arr.sort((a, b) => a - b) console.log(s) // [10,20,30,40,50]尾調(diào)用優(yōu)化
尾調(diào)用是什么鬼?
尾調(diào)用是指在函數(shù)return的時候調(diào)用一個新的函數(shù),由于尾調(diào)用的實現(xiàn)需要存儲到內(nèi)存中,在一個循環(huán)體中,如果存在函數(shù)的尾調(diào)用,你的內(nèi)存可能爆滿或溢出。
ES6中,引擎會幫你做好尾調(diào)用的優(yōu)化工作,你不需要自己優(yōu)化,但需要滿足下面3個要求:
1、函數(shù)不是閉包
2、尾調(diào)用是函數(shù)最后一條語句
3、尾調(diào)用結(jié)果作為函數(shù)返回
一個滿足以上要求的函數(shù)如下所示:
"use strict"; function a() { return b(); }
下面的都是不滿足的寫法:
//沒有return不優(yōu)化 "use strict"; function a() { b(); } //不是直接返回函數(shù)不優(yōu)化 "use strict"; function a() { return 1 + b(); } //尾調(diào)用是函數(shù)不是最后一條語句不優(yōu)化 "use strict"; function a() { const s = b(); return s } //閉包不優(yōu)化 "use strict"; function a() { const num = 1 function b() { return num } return b }
尾調(diào)用實際用途——遞歸函數(shù)優(yōu)化
在ES5時代,我們不推薦使用遞歸,因為遞歸會影響性能。
但是有了尾調(diào)用優(yōu)化之后,遞歸函數(shù)的性能有了提升。
//新型尾優(yōu)化寫法 "use strict"; function a(n, p = 1) { if(n <= 1) { return 1 * p } let s = n * p return a(n - 1, s) } //求 1 x 2 x 3的階乘 let sum = a(3) console.log(sum) // 6總結(jié)
函數(shù)這一章涉及到的知識點比較多,默認(rèn)參數(shù),命名參數(shù),不定參數(shù),展開運(yùn)算符,箭頭函數(shù),尾調(diào)用優(yōu)化。
第一次學(xué)習(xí)這些知識的人可以關(guān)注箭頭函數(shù)和展開運(yùn)算符的使用,這是最重要也最常用的知識,如果你已經(jīng)在項目中使用過這些知識,那么作為鞏固也是有幫助的,俗話說溫故知新。
=> 返回文章目錄
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/84056.html
摘要:在可迭代對象上使用所有數(shù)組上的新方法與方法與方法均接受兩個參數(shù)一個回調(diào)函數(shù)一個可選值用于指定回調(diào)函數(shù)內(nèi)部的。回調(diào)函數(shù)可接收三個參數(shù)數(shù)組的某個元素該元素對應(yīng)的索引位置以及該數(shù)組自身。 主要知識點:創(chuàng)建數(shù)組、數(shù)組上的新方法、類型化數(shù)組showImg(https://segmentfault.com/img/bVbfWo1?w=991&h=587); 《深入理解ES6》筆記 目錄 創(chuàng)建數(shù)組...
摘要:和都能夠聲明塊級作用域,用法和是類似的,的特點是不會變量提升,而是被鎖在當(dāng)前塊中。聲明常量,一旦聲明,不可更改,而且常量必須初始化賦值。臨時死區(qū)臨時死區(qū)的意思是在當(dāng)前作用域的塊內(nèi),在聲明變量前的區(qū)域叫做臨時死區(qū)。 主要知識點有:var變量提升、let聲明、const聲明、let和const的比較、塊級綁定的應(yīng)用場景showImg(https://segmentfault.com/img...
摘要:將對象的屬性拷貝到了對象,合并成一個新的對象。而這種行為也是新增的標(biāo)準(zhǔn)??偨Y(jié)本章講解了對象字面量語法拓展,新增方法,允許重復(fù)的對象字面量屬性,自有枚舉屬性排序,增強(qiáng)對象原型,明確了方法的定義。但是,就算把全部新增的功能記住也不是難事。 變量功能被加強(qiáng)了、函數(shù)功能被加強(qiáng)了,那么作為JavaScript中最普遍的對象,不加強(qiáng)對得起觀眾嗎? 對象類別 在ES6中,對象分為下面幾種叫法。(不需...
摘要:創(chuàng)建數(shù)組中創(chuàng)建數(shù)組的方式數(shù)組字面量一個數(shù)組。傳入一個回調(diào)函數(shù),找到數(shù)組中符合當(dāng)前搜索規(guī)則的第一個元素,返回它,并且終止搜索。用新元素替換掉數(shù)組內(nèi)的元素,可以指定替換下標(biāo)范圍。 ES5提供的數(shù)組已經(jīng)很強(qiáng)大,但是ES6中繼續(xù)改進(jìn)了一些,主要是增加了新的數(shù)組方法,所以這章的知識非常少。 創(chuàng)建數(shù)組 ES5中創(chuàng)建數(shù)組的方式:數(shù)組字面量、new一個數(shù)組。 const arr1 = [] //數(shù)組字...
閱讀 3855·2021-09-29 09:34
閱讀 3783·2021-09-27 13:34
閱讀 580·2021-09-24 09:47
閱讀 3045·2019-08-30 15:53
閱讀 1821·2019-08-26 13:54
閱讀 2096·2019-08-26 13:43
閱讀 545·2019-08-23 14:47
閱讀 1752·2019-08-23 14:28