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