JavaScriptの高次関数の魅力
7135 ワード
高次関数とは、少なくとも次の条件を満たす関数の1つである.関数はパラメータとして伝達され得る.2:関数は戻り値として出力され得る.
AOP(面に向かってプログラミングする)の主な役割はコア業務論理モジュールとは無関係な機能を抽出し、その後「動的に織り込む」方式で業務モジュールに組み込むことです.これらの機能は一般にログ統計、セキュリティ制御、異常処理などを含む.AOPはJava Springアーキテクチャの核心である.次に、Javascript種はどうやってAOPを実現するかを探ってみます.
JavaScriptの種類でAOPを実現するということは、一つの関数「動的編入」を他の関数に組み込むということです.具体的に実現される技術はたくさんあります.私たちは
curringについてまず何を話しますか?関数コリック化です.
curringはまた部分の価値を求めます.一つ
curringの関数は、まずいくつかのパラメータを受け入れ、これらのパラメータを受け入れた後、この関数はすぐに値を求めず、20は別の関数に戻り続け、先ほど入ってきたパラメータは関数によって形成されたクローズドに保存される.関数で本当に値を求める必要があるときは、その前に伝えられたすべてのパラメータを一度に値を求めるために使います.
硬い概念はよく分かりません.次の例を見てみます.一年の12ヶ月の消費を計算する関数が必要です.毎月の月末に私達はどれぐらいの金額を計算しますか?正常コードは以下の通りです アップロードの進捗度 … 次は高次関数の方法で関数節流を実現します.
流れ関数は頻繁に呼び出される制限関数の解を提供してくれる.次はもう一つの問題があります.いくつかの関数はユーザーから積極的に呼び出されますが、いくつかの客観的な原因で、これらの操作はページの性能に深刻な影響を与えます.この時は別の方法で解決しなければなりません.
もし私たちが短い時間でページに大量のDOMノードを挿入する必要があるなら、それは明らかにブラウザを辛くさせます.ブラウザの仮死を引き起こす可能性がありますので、分時関数を使って、いくつかのグループに分けて挿入します.
Web開発では、いくつかのブラウザの違いのため、いくつかの嗅覚作業が避けられない.
ブラウザの差異性のために、私たちは常に様々な互換性を持っています.非常に簡単で一般的な例を挙げてください.各ブラウザで通用するイベントバインディング関数です.
よくある書き方はこうです.
締め括りをつける
この文章は主に「Javascriptデザインモード」のまとめを読んでいます.
コードアドレス
原文の住所
JavaScript , JavaScript 。
高次関数実現AOPAOP(面に向かってプログラミングする)の主な役割はコア業務論理モジュールとは無関係な機能を抽出し、その後「動的に織り込む」方式で業務モジュールに組み込むことです.これらの機能は一般にログ統計、セキュリティ制御、異常処理などを含む.AOPはJava Springアーキテクチャの核心である.次に、Javascript種はどうやってAOPを実現するかを探ってみます.
JavaScriptの種類でAOPを実現するということは、一つの関数「動的編入」を他の関数に組み込むということです.具体的に実現される技術はたくさんあります.私たちは
Function.prototype
を使ってこの点を達成します.コードは以下の通りです/**
*
* @param {*} fn
*/
Function.prototype.aopBefore = function(fn){
console.log(this)
// :
const _this = this
// : “ ”
return function() {
// : , this
fn.apply(this, arguments)
//
return _this.apply(this, arguments)
}
}
/**
*
* @param {*} fn
*/
Function.prototype.aopAfter = function (fn) {
const _this = this
return function () {
let current = _this.apply(this,arguments)//
fn.apply(this, arguments) //
return current
}
}
/**
*
*/
let aopFunc = function() {
console.log('aop')
}
//
aopFunc = aopFunc.aopBefore(() => {
console.log('aop before')
}).aopAfter(() => {
console.log('aop after')
})
//
aopFunc()
currying(カリー化)curringについてまず何を話しますか?関数コリック化です.
curringはまた部分の価値を求めます.一つ
curringの関数は、まずいくつかのパラメータを受け入れ、これらのパラメータを受け入れた後、この関数はすぐに値を求めず、20は別の関数に戻り続け、先ほど入ってきたパラメータは関数によって形成されたクローズドに保存される.関数で本当に値を求める必要があるときは、その前に伝えられたすべてのパラメータを一度に値を求めるために使います.
硬い概念はよく分かりません.次の例を見てみます.一年の12ヶ月の消費を計算する関数が必要です.毎月の月末に私達はどれぐらいの金額を計算しますか?正常コードは以下の通りです
//
let totalCost = 0
const cost = function(amount, mounth = '') {
console.log(` ${mounth} ${amount}`)
totalCost += amount
console.log(` :${totalCost}`)
}
cost(1000, 1) // 1
cost(2000, 2) // 2
// ...
cost(3000, 12) // 12
まとめてみます.一年間の総消費を計算するなら、12回計算する必要はありません.年末に計算を一回実行すればいいです.これからはこの関数の部分的なコリゼーションの関数を理解してくれます.//
const curringPartCost = (function() {
//
let args = []
return function (){
/**
*
*
*
*/
if (arguments.length === 0) {
let totalCost = 0
args.forEach(item => {
totalCost += item[0]
})
console.log(` :${totalCost}`)
return totalCost
} else {
// argumens ,
let currentArgs = Array.from(arguments)
args.push(currentArgs)
console.log(` ${arguments[1] ? arguments[1] : '' } , ${arguments[0]}`)
}
}
})()
curringPartCost(1000,1)
curringPartCost(100,2)
curringPartCost()
次に一般的なcurringを作成し,間もなくcurringの関数になる.コードは以下の通りです// curring
const curring = function(fn) {
let args = []
return function () {
if (arguments.length === 0) {
console.log('curring ')
return fn.apply(this, args)
} else {
let currentArgs = Array.from(arguments)[0]
console.log(` ${arguments[1] ? arguments[1] : '' } , ${arguments[0]}`)
args.push(currentArgs)
// Function , Function ,
return arguments.callee
}
}
}
//
let costCurring = (function() {
let totalCost = 0
return function () {
for (let i = 0; i < arguments.length; i++) {
totalCost += arguments[i]
}
console.log(` :${totalCost}`)
return totalCost
}
})()
// curring
costCurring = curring(costCurring)
costCurring(2000, 1)
costCurring(2000, 2)
costCurring(9000, 12)
costCurring()
葃関数節流JavaScriptの大多数の関数はユーザーが主導的にトリガしたもので、一般的には性能の問題はないが、いくつかの特殊な状況ではユーザーによって直接制御されない.大量の呼び出しがしやすく、性能に問題があります.なにしろDOM動作の価格は非常に高価である.以下では、このような場面をいくつか挙げます.window.resise
事件です.mouse, input
などの事件./**
*
* @param {*} fn
* @param {*} interval
*/
const throttle = function (fn, interval = 500) {
let timer = null, //
isFirst = true //
return function () {
let args = arguments, _me = this
//
if (isFirst) {
fn.apply(_me, args)
return isFirst = false
}
//
if (timer) {
return false
}
// timer
timer = setTimeout(function (){
console.log(timer)
window.clearTimeout(timer)
timer = null
fn.apply(_me, args)
}, interval)
}
}
//
window.onresize = throttle(function() {
console.log('throttle')
},600)
時分関数流れ関数は頻繁に呼び出される制限関数の解を提供してくれる.次はもう一つの問題があります.いくつかの関数はユーザーから積極的に呼び出されますが、いくつかの客観的な原因で、これらの操作はページの性能に深刻な影響を与えます.この時は別の方法で解決しなければなりません.
もし私たちが短い時間でページに大量のDOMノードを挿入する必要があるなら、それは明らかにブラウザを辛くさせます.ブラウザの仮死を引き起こす可能性がありますので、分時関数を使って、いくつかのグループに分けて挿入します.
/**
*
* @param {* } list
* @param {* } fn
* @param {* } count
*/
const timeChunk = function(list, fn, count = 1){
let insertList = [], //
timer = null //
const start = function(){
//
for (let i = 0; i < Math.min(count, list.length); i++) {
insertList = list.shift()
fn(insertList)
}
}
return function(){
timer = setInterval(() => {
if (list.length === 0) {
return window.clearInterval(timer)
}
start()
},200)
}
}
//
const arr = []
for (let i = 0; i < 94; i++) {
arr.push(i)
}
const renderList = timeChunk(arr, function(data){
let div =document.createElement('div')
div.innerHTML = data + 1
document.body.appendChild(div)
}, 20)
renderList()
不活性負荷関数Web開発では、いくつかのブラウザの違いのため、いくつかの嗅覚作業が避けられない.
ブラウザの差異性のために、私たちは常に様々な互換性を持っています.非常に簡単で一般的な例を挙げてください.各ブラウザで通用するイベントバインディング関数です.
よくある書き方はこうです.
//
const addEvent = function(el, type, handler) {
if (window.addEventListener) {
return el.addEventListener(type, handler, false)
}
// for IE
if (window.attachEvent) {
return el.attachEvent(`on${type}`, handler)
}
}
この関数は実行するたびにif条件分岐を実行する欠点がある.お金はあまりかかりませんが、これは明らかに余分です.次は最適化して、事前に嗅いでみましょう.const addEventOptimization = (function() {
if (window.addEventListener) {
return (el, type, handler) => {
el.addEventListener(type, handler, false)
}
}
// for IE
if (window.attachEvent) {
return (el, type, handler) => {
el.attachEvent(`on${type}`, handler)
}
}
})()
このようにコードを読み込む前に一回嗅覚を行い、関数を返します.しかし、私たちがそれを公共の倉庫に入れて使用しないと、ちょっと余分です.以下は不活性関数を使ってこの問題を解決します.//
let addEventLazy = function(el, type, handler) {
if (window.addEventListener) {
// ,
addEventLazy = function(el, type, handler) {
el.addEventListener(type, handler, false)
}
} else if (window.attachEvent) {
addEventLazy = function(el, type, handler) {
el.attachEvent(`on${type}`, handler)
}
}
addEventLazy(el, type, handler)
}
addEventLazy(document.getElementById('eventLazy'), 'click', function() {
console.log('lazy ')
})
分岐に入ると、関数の内部で関数の実装を変更し、書き換えた後、関数は私たちが期待する関数であり、次の関数に入ると条件分岐文は存在しなくなります.締め括りをつける
この文章は主に「Javascriptデザインモード」のまとめを読んでいます.
コードアドレス
原文の住所