Home >Web Front-end >JS Tutorial >JS array flattening, anti-shaking and throttling object copying

JS array flattening, anti-shaking and throttling object copying

php中世界最好的语言
php中世界最好的语言Original
2018-06-14 11:20:291749browse

This time I will bring you JS array flattening anti-shake and throttling object copying. What are the precautions for JS array flattening anti-shaking and throttling object copying? Here is a practical case, let’s take a look.

Array flattening

There are many methods for array flattening, but in the end the best method is recursion to achieve a specified depth of flattening Method, so that you will understand the basic routines.

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 ]

The recursive implementation is very simple and easy to understand, that is, traversing each item. If an item is an array, let the item continue to be called. Depth is specified here as the flattening depth, because this parameter is important for the array. Every item of has a role to play, so it is placed inside the loop.

Currying

Currying of functions has been talked about badly. Everyone has their own understanding and implementation method. In one sentence The explanation is that if there are enough parameters, it will be executed. If there are not enough parameters, a function will be returned. The previous parameters will be stored until there are enough.

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]

It is not difficult to see from the above code that each time the number of parameters is judged, it is compared with the number of curried function parameters. If it is less than the number, it will continue to return to the function, otherwise it will be executed.

Anti-shake

According to my understanding, anti-shake means that no matter how many times you trigger it, it will wait until a period of time you specify after the last trigger. Time is triggered. Following this explanation, write a basic version.

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

Now there is a requirement that it will be triggered at the beginning and the last time, and it can be configured. First, write a test page to facilitate testing the function. Each time you press the space bar, the number will increase by 1. Test anti-shake and throttling functions.

<!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>

Determine whether the start and end are executed through the two parameters leading and trailing. If leading is true, it will be executed once every time you press space. If trailing is true, the last trigger will be triggered every time you end. implement. Anti-shake function distance, if both are true, pressing space for the first time will add 1, and then pressing space quickly, the getUserAction inside will not be executed at this time, but will be executed after letting go. Add trailing to false , it will not be executed after letting go.

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)
 }
 }
}

Explain, each time the time of the last call is recorded, compare it with the current time. If it is less than the interval, it will not be executed after the first execution. If it is greater than the interval or called after the interval, Then reset the flag and compare it with the basic version above.

Throttling

Throttling means that no matter how it is triggered, it will be executed according to the specified interval. We also give a basic version.

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)
 }
 }
}

It also adds two parameters like the anti-shake function. You can also use the above example to test. In fact, the codes of the two are very similar.

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
 }
 }
}

Object copy

We all know that object copy is divided into deep copy and shallow copy. The black technology method is to use

JSON.parse(JSON.stringify(obj))

Another method is to use recursion

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

I believe you have mastered the method after reading the case in this article, and more How exciting, please pay attention to other related articles on php Chinese website!

Recommended reading:

How to use the better-scroll plug-in in the project

jQuery Cookie switching style

The above is the detailed content of JS array flattening, anti-shaking and throttling object copying. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn