一般的な JS 関数のまとめ

php中世界最好的语言
php中世界最好的语言オリジナル
2018-05-03 15:02:541374ブラウズ

今回はJSのよく使われる関数と、JSのよく使われる関数を使用する際の注意点について、実際の事例を交えて見ていきましょう。

配列の平坦化

配列を平坦化する方法はたくさんありますが、最終的に最善の方法は、基本的なルーチンを理解できるように、指定された深さで平坦化メソッドを再帰して実装することです。

function flattenDepth(array, depth = 1) {
 let result = []
 array.forEach(item => {
 let d = depth
 if (Array.isArray(item) && d > 0) {
  result.push(...(flattenDepth(item, --d)))
 } else {
  result.push(item)
 }
 })
 return result
}
console.log(flattenDepth([1, [2, [3, [4]], 5]])) // [ 1, 2, [ 3, [ 4 ] ], 5 ]
console.log(flattenDepth([1, [2, [3, [4]], 5]], 2)) // [ 1, 2, 3, [ 4 ], 5 ]
console.log(flattenDepth([1, [2, [3, [4]], 5]], 3)) // [ 1, 2, 3, 4, 5 ]

再帰的な実装は非常にシンプルで理解しやすいです。つまり、項目が配列の場合、このパラメーターは各項目に影響を与えるため、その項目を引き続き呼び出すようにします。これらはすべて役割を持っているため、ループ内に配置されます。

カリー化

関数のカリー化については、人によって理解や実装方法が異なります。一言で説明すると、パラメータが十分であれば実行され、パラメータが十分でなければ実行されます。パラメータを指定すると、関数が返されます。以前のパラメータは、十分な数が必要になるまで保存されます。

function curry(func) {
 var l = func.length
 return function curried() {
 var args = [].slice.call(arguments)
 if(args.length < l) {
  return function() {
  var argsInner = [].slice.call(arguments)
  return curried.apply(this, args.concat(argsInner))
  }
 } else {
  return func.apply(this, args)
 }
 }
}
var f = function(a, b, c) {
 return console.log([a, b, c])
};
var curried = curry(f)
curried(1)(2)(3) // => [1, 2, 3]
curried(1, 2)(3) // => [1, 2, 3]
curried(1, 2, 3) // => [1, 2, 3]

パラメータの数が判断されるたびに、カリー化された関数パラメータの数と比較され、それがその数より小さい場合は、それが返され続けることは、上記のコードからわかります。それ以外の場合は関数が実行されます。

手ぶれ補正

私の理解によれば、手ぶれ補正とは、何度トリガーしても、最後のトリガーから指定した時間が経過するまではトリガーされないことを意味します。この説明に続いて、基本バージョンを作成します。

function debounce(func, wait) {
 var timer
 return function() {
 var context = this
 var args = arguments
 clearTimeout(timer)
 timer = setTimeout(function() {
  func.apply(context, args)
 }, wait)
 }
}

ここで、最初と最後にトリガーするという要件があり、これを設定できます。まず、スペースバーを押すたびに、関数のテストを容易にするためにテストページを作成します。手ぶれ補正とスロットル機能をテストするには、1 ずつ増やします。

<!DOCTYPE html>
<html lang="zh-cmn-Hans">
<head>
 <style>
  #container{text-align: center; color: #333; font-size: 30px;}
 </style>
</head>
<body>
 <p id="container"></p>
 <script>
  var count = 1
  var container = document.getElementById('container')
  function getUserAction(e) {
  // 空格
  if (e.keyCode === 32) {
   container.innerHTML = count++
  }
  }
  // document.onkeydown = debounce(getUserAction, 1000, false, true)
  document.onkeydown = throttle(getUserAction, 1000, true, true)
  function debounce(func, wait, leading, trailing) {}
  function throttle(func, wait, leading, trailing) {}
 </script>
</body>
</html>

先頭と末尾の 2 つのパラメータで開始と終了を実行するかどうかを決定します。先頭が true の場合、スペースを押すたびに 1 回実行されます。末尾が true の場合、終了するたびに最後のトリガーが実行されます。 。手ぶれ補正機能の距離、両方が true の場合、最初にスペースを押すと 1 が追加され、すぐにスペースを押すと、この時点では内部の getUserAction は実行されませんが、末尾を false に放した後に実行されます。 、手放した後は実行されません。

function debounce(func, wait, leading, trailing) {
 var timer, lastCall = 0, flag = true
 return function() {
 var context = this
 var args = arguments
 var now = + new Date()
 if (now - lastCall < wait) {
  flag = false
  lastCall = now
 } else {
  flag = true
 }
 if (leading && flag) {
  lastCall = now
  return func.apply(context, args)
 }
 if (trailing) {
  clearTimeout(timer)
  timer = setTimeout(function() {
  flag = true
  func.apply(context, args)
  }, wait)
 }
 }
}

説明します、最後の呼び出しの時間が記録されるたびに、それが間隔より小さい場合、最初の実行後または呼び出された後は実行されません。一定の時間が経過するとフラグがリセットされ、上記の基本バージョンと比較できます。

スロットリング

スロットルとは、どのようにトリガーされたとしても、指定された間隔に従って実行されることを意味します。 基本バージョンもあります。

function throttle(func, wait) {
 var timer
 return function() {
 var context = this
 var args = arguments
 if (!timer) {
  timer = setTimeout(function () {
  timer = null
  func.apply(context, args)
  }, wait)
 }
 }
}

手ぶれ補正機能のような 2 つのパラメーターも追加します。実際、この 2 つのコードは非常に似ています。

function throttle(func, wait, leading, trailing) {
 var timer, lastCall = 0, flag = true
 return function() {
 var context = this
 var args = arguments
 var now = + new Date()
 flag = now - lastCall > wait
 if (leading && flag) {
  lastCall = now
  return func.apply(context, args)
 }
 if (!timer && trailing && !(flag && leading)) {
  timer = setTimeout(function () {
  timer = null
  lastCall = + new Date()
  func.apply(context, args)
  }, wait)
 } else {
  lastCall = now
 }
 }
}

オブジェクトコピー

オブジェクトコピーが深いコピーと浅いコピーに分けられることは誰もが知っています

JSON.parse(JSON.stringify(obj))

もう一つの方法は再帰を使用することです

function clone(value, isDeep) {
 if (value === null) return null
 if (typeof value !== 'object') return value
 if (Array.isArray(value)) {
 if (isDeep) {
  return value.map(item => clone(item, true))
 }
 return [].concat(value)
 } else {
 if (isDeep) {
  var obj = {}
  Object.keys(value).forEach(item => {
  obj[item] = clone(value[item], true)
  })
  return obj
 }
 return { ...value }
 }
}
var objects = { c: { 'a': 1, e: [1, {f: 2}] }, d: { 'b': 2 } }
var shallow = clone(objects, true)
console.log(shallow.c.e[1]) // { f: 2 }
console.log(shallow.c === objects.c) // false
console.log(shallow.d === objects.d) // false
console.log(shallow === objects) // false

基本的なタイプの場合、参照型の場合は、clone メソッドが再帰的に呼び出されます。

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

推奨読書:

Vue ドキュメントのエラーが発生しやすいポイントを整理

Angular CLI ルーティング生成手順の詳細な説明

以上が一般的な JS 関数のまとめの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。