javascript
1 access中iif函数中的_JavaScript中的高阶函数
前言
在 JavaScript 的學習過程中,我們可能或多或少地接觸過高階函數。那么,我們自己對此是否有一個明確的定義,或者說很熟練的掌握這些用法呢
如果文章中有出現紕漏、錯誤之處,還請看到的小伙伴多多指教,先行謝過
以下↓
簡單來說,高階函數是一個函數,它接收函數作為參數或將函數作為輸出返回看到這樣的概念,在你的腦海中會出現哪些函數呢
其實,像我們經常會使用到的一些數組方法,比如:map、filter 等等都是高階函數的范疇
當然,這些 JavaScript 內置的方法不在本文的討論范圍之內,下面會列舉一些在我們實際開發或者面試過程中可能會遇到的函數高階用法
防抖
任務頻繁觸發的情況下,只有任務觸發的間隔超過指定間隔的時候,任務才會執行實現方式就是如果任務觸發的頻率比我們設定的時間要小,那么我們就清除掉上一個任務重新計時
function debounce(fn, interval) {let timer = null
return function() {
// 如果用戶在設定的時間內再次觸發,就清除掉
clearTimeout(timer)
timer = setTimeout(() => {
fn.apply(this, arguments)
}, interval);
}
}
節流
指定時間間隔內只會執行一次任務 function throttle(fn, interval) {let timer,
firstTime = true // 是否是第一次執行
return function () {
let _this = this
if (firstTime) {
fn.apply(_this, arguments) // 第一次不需要延遲執行
return firstTime = false
}
if (timer) { // 如果定時器還在 說明前一次還沒有執行完
return false
}
timer = setTimeout(() => {
clearTimeout(timer)
timer = null
fn.apply(_this, arguments)
}, interval || 500);
}
}
// 不考慮定時器的情況 直接加一個節流閥
function throttle(fn, interval) {
let canRun = true //節流閥
return function() {
if(!canRun) {
return
}
canRun = false
setTimeout(() => {
fn.apply(this, arguments)
canRun = true
}, interval);
}
}
無論是防抖還是節流,我們都可以使用下面的這種方式去驗證一下
window.onresize = throttle(function () {console.log(1)
}, 1000)
通過上面兩種方式的實現,相信小伙伴們也都了解了所謂防抖和節流我們都是借助 setTimeOut 來實現,不同的地方就是 清除定時器的位置
惰性函數
當我們需要重復使用一個邏輯的時候,優化邏輯判斷,提高 JavaScript 性能原理:同名函數覆蓋
function createXHR() {var xhr
try {
xhr = new XMLHttpRequest()
} catch (e) {
handleErr(e)
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP')
} catch (e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
} catch (e) {
xhr = null
}
}
}
return xhr
}
function handleErr(e) {
// do sth
}
惰性函數修改版:
function createXHR() {var xhr
if(typeof XMLHttpRequest !== 'undefined') {
xhr = new XMLHttpRequest()
}
createXHR = function() {
return new XMLHttpRequest()
} else {
try {
xhr = new ActiveXObject('Msxml2.XMLHTTP')
createXHR = function() {
return new ActiveXObject('Msxml2.XMLHTTP')
}
} catch(e) {
try {
xhr = new ActiveXObject('Microsoft.XMLHTTP')
createXHR = function() {
return new ActiveXObject('Microsoft.XMLHTTP')
}
} catch(e) {
createXHR = function() {
return null
}
}
}
}
return xhr
}
通過上面修改之后,當我們在第一次調用這個函數的時候就會去判斷當前的環境,進而將函數優化簡寫,不需要再進行后續的判斷
比如,上述代碼中的 XMLHTTPRequest 如果是存在的,那么當我們第二次調用這個函數的時候已經是這樣了
function createXHR() {return new XMLHttpRequest()
}
使用場景:
頻繁使用同一判斷邏輯
只需要判斷一次,后續使用環境穩定
級聯函數
其實就是鏈式調用,所以原理也就很簡單:在每個方法中將對象本身 return 出去
假設我們有一個 Person 模板
function Person() {}// 添加幾個方法
Person.prototype = {
setName: function (name) {
this.name = name
return this //
},
setAge: function (age) {
this.age = age
return this
},
setSex: function (sex) {
this.sex = sex
},
}
// 別忘了重新指定一下構造函數
Person.constructor = Person
let person = new Person()
// 這樣看起來做了很多重復的事情,稍微修改一下,在每個方法中將 this return 出來就可以達到 鏈式調用的效果
person.setName('游蕩de蝌蚪')
person.setAge(18)
person.setSex('male')
// 修改之后
person.setName('游蕩de蝌蚪').setAge(18).setSex('male')
console.log(person)
優點:簡化了函數調用的步驟,我們不需要再寫一些重復的東西
缺點:占用了函數的返回值
柯里化
收集參數,延后執行,也可以稱之為部分求值 function add(a, b) {return a + b
}
// 簡單的通用封裝
function curry(fn) {
let args = Array.prototype.slice.call(arguments, 1)
return function() {
let _args = Array.prototype.slice.call(arguments)
let final = args.concat(_args)
return fn.apply(null, final)
}
}
// 對函數 add 柯里化
let adder = curry(add)
adder(1, 2)
// 或者
let adder = curry(add, 1)(2)
let adder = curry(add)(1, 2)
一個典型的通用型 curry 封裝
Function.prototype.mybind = function(fn) {let args = Array.prototype.slice(arguments, 1)
let _this = this
return function() {
let _args = Array.prototype.slice(arguments)
let final = args.concat(_args)
return _this.apply(fn, final)
}
}
通過 curry 函數的這種模式,我們就能實現一個簡單的 bind
Function.prototype.mybind = function(fn) {let _this = this
return function() {
return _this.apply(fn, arguments)
}
}
函數柯里化也是我們在面試過程中可能會經常碰到的問題,比如:
// 編寫一個 add 函數,實現以下功能add(1)(2)(3) // 6
add(1)(2, 3)(4) //10
add(1, 2)(3) (4, 5) // 15
function add() {
let args = Array.prototype.slice.call(arguments)
let adder = function() {
// 利用閉包的特性保存 args 并且收集參數
args = args.concat(Array.prototype.slice.call(arguments))
return adder
}
// 利用 toString 隱式轉換的的特性返回最終計算的值
adder.toString = function() {
return args.reduce((a, b) => {
return a + b
})
}
return adder
}
add(1)(2)(3) // 6
add(1)(2, 3)(4) // 10
add(1, 2)(3)(4, 5) // 15
// 當然,我們也可以借助ES6的方法簡化這個函數
function add1(...args) {
let adder = (..._args) => {
args = [...args, ..._args]
return adder
}
adder.toString = () => args.reduce((a, b) => a + b)
return adder
}
想要實現上面函數的效果,我覺得有兩點是我們必須理解和掌握的:
閉包,使用閉包的特性去保存和收集我們需要的參數
利用 toString 的隱式轉換特性,最終拿到我們想要的結果
后記
看完以上幾個函數高階用法的實例,你的第一感覺是什么呢
閉包啊!作為一位合格的前端,閉包是我們必須去征服的一個知識點
總結
以上是生活随笔為你收集整理的1 access中iif函数中的_JavaScript中的高阶函数的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python人脸识别从入门到工程pdf_
- 下一篇: jpa 动态查询条件 数组_Spring