'中級前端工程師必須要掌握的 20 個 JavaScript 技巧,你呢?'
1.判斷對象的數據類型
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
和函數防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發,同時新增了 trailing 選項,表示是否在最後額外觸發一次
19. 圖片懶加載
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
和函數防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發,同時新增了 trailing 選項,表示是否在最後額外觸發一次
19. 圖片懶加載
getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件添加節流),圖片加載完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片加載完畢後需要解綁監聽事件
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
和函數防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發,同時新增了 trailing 選項,表示是否在最後額外觸發一次
19. 圖片懶加載
getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件添加節流),圖片加載完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片加載完畢後需要解綁監聽事件
intersectionObserver 的實現方式,實例化一個 IntersectionObserver ,並使其觀察所有 img 標籤
當 img 標籤進入可視區域時會執行實例化時的回調,同時給回調傳入一個 entries 參數,保存著實例觀察的所有元素的一些狀態,比如每個元素的邊界信息,當前元素對應的 DOM 節點,當前元素進入可視區域的比率,每當一個元素進入可視區域,將真正的圖片賦值給當前 img 標籤,同時解除對其的觀察
20. new 關鍵字
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
和函數防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發,同時新增了 trailing 選項,表示是否在最後額外觸發一次
19. 圖片懶加載
getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件添加節流),圖片加載完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片加載完畢後需要解綁監聽事件
intersectionObserver 的實現方式,實例化一個 IntersectionObserver ,並使其觀察所有 img 標籤
當 img 標籤進入可視區域時會執行實例化時的回調,同時給回調傳入一個 entries 參數,保存著實例觀察的所有元素的一些狀態,比如每個元素的邊界信息,當前元素對應的 DOM 節點,當前元素進入可視區域的比率,每當一個元素進入可視區域,將真正的圖片賦值給當前 img 標籤,同時解除對其的觀察
20. new 關鍵字
源代碼
實現代碼較長,這裡我直接貼上對應源代碼地址 JSON.stringify,歡迎 star,以後有後續的技巧會第一時間添加新的內容
最後,小編為大家準備了前端的視頻教程和自學資料,希望能幫到大家
1.判斷對象的數據類型
使用 Object.prototype.toString 配合閉包,通過傳入不同的判斷類型來返回不同的判斷函數,一行代碼,簡潔優雅靈活(注意傳入 type 參數時首字母大寫)
不推薦將這個函數用來檢測可能會產生包裝類型的基本數據類型上,因為 call 會將第一個參數進行裝箱操作
2. 循環實現數組 map 方法
使用方法:將 selfMap 注入到 Array.prototype 上(下面數組的迭代方法同理)
值得一提的是,map 的第二個參數為第一個參數回調中的 this 指向,如果第一個參數為箭頭函數,那設置第二個 this 會因為箭頭函數的詞法綁定而失效
另外就是對稀疏數組的處理,通過 hasOwnProperty 來判斷當前下標的元素是否存在與數組中(感謝評論區的朋友)
3. 使用 reduce 實現數組 map 方法
4. 循環實現數組 filter 方法
5. 使用 reduce 實現數組 filter 方法
6. 循環實現數組的 some 方法
執行 some 方法的數組如果是一個空數組,最終始終會返回 false,而另一個數組的 every 方法中的數組如果是一個空數組,會始終返回 true
7. 循環實現數組的 reduce 方法
因為可能存在稀疏數組的關係,所以 reduce 需要保證跳過稀疏元素,遍歷正確的元素和下標(感謝@神三元的提供的代碼)
8. 使用 reduce 實現數組的 flat 方法
因為 selfFlat 是依賴 this 指向的,所以在 reduce 遍歷時需要指定 selfFlat 的 this 指向,否則會默認指向 window 從而發生錯誤
原理通過 reduce 遍歷數組,遇到數組的某個元素仍是數組時,通過 ES6 的擴展運算符對其進行降維(ES5 可以使用 concat 方法),而這個數組元素可能內部還嵌套數組,所以需要遞歸調用 selfFlat
同時原生的 flat 方法支持一個 depth 參數表示降維的深度,默認為 1 即給數組降一層維度
傳入 Inifity 會將傳入的數組變成一個一維數組
原理是每遞歸一次將 depth 參數減 1,如果 depth 參數為 0 時,直接返回原數組
9. 實現 ES6 的 class 語法
ES6 的 class 內部是基於寄生組合式繼承,它是目前最理想的繼承方式,通過 Object.create 方法創造一個空對象,並將這個空對象繼承 Object.create 方法的參數,再讓子類(subType)的原型對象等於這個空對象,就可以實現子類實例的原型等於這個空對象,而這個空對象的原型又等於父類原型對象(superType.prototype)的繼承關係
而 Object.create 支持第二個參數,即給生成的空對象定義屬性和屬性描述符/訪問器描述符,我們可以給這個空對象定義一個 constructor 屬性更加符合默認的繼承行為,同時它是不可枚舉的內部屬性(enumerable:false)
而 ES6 的 class 允許子類繼承父類的靜態方法和靜態屬性,而普通的寄生組合式繼承只能做到實例與實例之間的繼承,對於類與類之間的繼承需要額外定義方法,這裡使用 Object.setPrototypeOf 將 superType 設置為 subType 的原型,從而能夠從父類中繼承靜態方法和靜態屬性
10. 函數柯里化
使用方法:
柯里化是函數式編程的一個重要技巧,將使用多個參數的一個函數轉換成一系列使用一個參數的函數的技術
函數式編程另一個重要的函數 compose,能夠將函數進行組合,而組合的函數只接受一個參數,所以如果有接受多個函數的需求並且需要用到 compose 進行函數組合,就需要使用柯里化對準備組合的函數進行部分求值,讓它始終只接受一個參數
借用一個例子
11. 函數柯里化(支持佔位符)
使用方法:
通過佔位符能讓柯里化更加靈活,實現思路是,每一輪傳入的參數先去填充上一輪的佔位符,如果當前輪參數含有佔位符,則放到內部保存的數組末尾,當前輪的元素不會去填充當前輪參數的佔位符,只會填充之前傳入的佔位符
12. 偏函數
使用方法:
偏函數和柯里化概念類似,個人認為它們區別在於偏函數會固定你傳入的幾個參數,再一次性接受剩下的參數,而函數柯里化會根據你傳入參數不停的返回函數,直到參數個數滿足被柯里化前函數的參數個數
Function.prototype.bind 函數就是一個偏函數的典型代表,它接受的第二個參數開始,為預先添加到綁定函數的參數列表中的參數,與 bind 不同的是,上面的這個函數同樣支持佔位符
13. 斐波那契數列及其優化
利用函數記憶,將之前運算過的結果保存下來,對於頻繁依賴之前結果的計算能夠節省大量的時間,例如斐波那契數列,缺點就是閉包中的 obj 對象會額外佔用內存
14. 實現函數 bind 方法
函數的 bind 方法核心是利用 call,同時考慮了一些其他情況,例如
bind 返回的函數被 new 調用作為構造函數時,綁定的值會失效並且改為 new 指定的對象
定義了綁定後函數的 length 屬性和 name 屬性(不可枚舉屬性)
綁定後函數的原型需指向原來的函數
15. 實現函數 call 方法
原理就是將函數作為傳入的上下文參數(context)的屬性執行,這裡為了防止屬性衝突使用了 ES6 的 Symbol 類型
16. 簡易的 CO 模塊
使用方法:
run 函數接受一個生成器函數,每當 run 函數包裹的生成器函數遇到 yield 關鍵字就會停止,當 yield 後面的 promise 被解析成功後會自動調用 next 方法執行到下個 yield 關鍵字處,最終就會形成每當一個 promise 被解析成功就會解析下個 promise,當全部解析成功後打印所有解析的結果,衍變為現在用的最多的 async/await 語法
17. 函數防抖
leading 為是否在進入時立即執行一次,原理是利用定時器,如果在規定時間內再次觸發事件會將上次的定時器清除,即不會執行函數並重新設置一個新的定時器,直到超過規定時間自動觸發定時器中的函數
同時通過閉包向外暴露了一個 cancel 函數,使得外部能直接清除內部的計數器
18. 函數節流
和函數防抖類似,區別在於內部額外使用了時間戳作為判斷,在一段時間內沒有觸發事件才允許下次事件觸發,同時新增了 trailing 選項,表示是否在最後額外觸發一次
19. 圖片懶加載
getBoundClientRect 的實現方式,監聽 scroll 事件(建議給監聽事件添加節流),圖片加載完會從 img 標籤組成的 DOM 列表中刪除,最後所有的圖片加載完畢後需要解綁監聽事件
intersectionObserver 的實現方式,實例化一個 IntersectionObserver ,並使其觀察所有 img 標籤
當 img 標籤進入可視區域時會執行實例化時的回調,同時給回調傳入一個 entries 參數,保存著實例觀察的所有元素的一些狀態,比如每個元素的邊界信息,當前元素對應的 DOM 節點,當前元素進入可視區域的比率,每當一個元素進入可視區域,將真正的圖片賦值給當前 img 標籤,同時解除對其的觀察
20. new 關鍵字
源代碼
實現代碼較長,這裡我直接貼上對應源代碼地址 JSON.stringify,歡迎 star,以後有後續的技巧會第一時間添加新的內容
最後,小編為大家準備了前端的視頻教程和自學資料,希望能幫到大家