5 つの一般的な JavaScript 関数のまとめ

零到壹度
リリース: 2018-04-02 09:13:55
オリジナル
1136 人が閲覧しました

JavaScript には頻繁に議論される問題がいくつかあります。これらの問題を理解するための最良の方法は、早速、本題に取り掛かります。 この記事では、5 つの一般的な JavaScript 関数の概要を紹介します。この内容が、困っている友人に役立つことを願っています。 配列の平坦化

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

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 ]
ログイン後にコピー
  1. 再帰的な実装は非常にシンプルで理解しやすいです。つまり、各項目を走査し、項目が配列の場合、その項目を平坦化の深さとしてここで指定し続けます。このパラメータは配列にとって重要であるため、 の各項目には役割があるため、ループ内に配置されます。

カリー化

関数のカリー化については、人によって理解や実装方法が異なります。 一言で説明すると、

パラメーターが十分であれば実行されます。前のパラメータは関数を返します。十分な数になるまで保存します

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]
ログイン後にコピー
  1. 上記のコードからわかることは難しくありませんが、パラメータの数が判断されるたびに、カリー化された関数のパラメータの数よりも小さい場合は継続されます。関数を返すか、それ以外の場合は関数が実行されます。

手ぶれ補正

私の理解によれば、手ぶれ補正とは、何度トリガーしても、最後のトリガー

から指定した時間が経過するまではトリガーされないことを意味します。この説明に続いて、基本バージョンを作成します。

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. ここで、最初と最後にトリガーされるという要件があり、スペースバーを押すたびに関数をテストしやすくするためにテストページを作成します。 、数値は 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(&#39;container&#39;)
      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>
ログイン後にコピー

  1. 先頭と末尾の 2 つのパラメータは、先頭が true の場合、スペースが押されるたびに 1 回実行され、末尾が true の場合は、最後のトリガーが実行されます。実装が終了するたびにトリガーされます。手ぶれ補正機能の距離、両方が true の場合、最初にスペースを押すと 1 が追加され、すぐにスペースを押すと、この時点では内部の getUserAction は実行されませんが、末尾を false に放した後に実行されます。 、手放した後は実行されません。
    1. 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)
          }
        }
      }
      ログイン後にコピー

    解释一下,每次记录上次调用的时间,与现在的时间对比,小于间隔的话,第一次执行后之后就不会执行,大于间隔或在间隔时间后调用了,则重置 flag,可以与上面那个基本版的对比着看。

    节流

    节流就是,不管怎么触发,都是按照指定的间隔来执行,同样给个基本版。

    1. 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)
          }
        }
      }
      ログイン後にコピー

    同样和防抖函数一样加上两个参数,也可使用上面的例子来测试,其实两者的代码很类似。

    1. 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
          }
        }
      }
      ログイン後にコピー

    对象拷贝

    对象拷贝都知道分为深拷贝和浅拷贝,黑科技手段就是使用

    1. JSON.parse(JSON.stringify(obj))
      ログイン後にコピー

    还有个方法就是使用递归了

    1. function clone(value, isDeep) {
        if (value === null) return null
        if (typeof value !== &#39;object&#39;) 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: { &#39;a&#39;: 1, e: [1, {f: 2}] }, d: { &#39;b&#39;: 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 方法。

      总结

      其实对于上面这些方法,总的来说思路就是递归和高阶函数的使用,其中就有关于闭包的使用,前端就爱问这些问题,最好就是自己实现一遍,这样有助于理解。

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

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート