Home > Web Front-end > JS Tutorial > body text

Detailed explanation of five common functions in JavaScript

小云云
Release: 2018-03-26 09:07:52
Original
1289 people have browsed it

There are some issues in JavaScript that are often discussed. Everyone has different ideas about these issues. The best way to understand these issues is to implement them yourself. Without further ado, let’s get down to the topic.

Array flattening

There are many ways to flatten arrays, but in the end the best way is to recurse and implement a flattening method with a specified depth, so that you can 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 ]
Copy after login

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. The depth is specified here as the flat Depth of optimization, because this parameter affects every item in the array, it is placed inside the loop.

Currying

Currying of functions has been talked about badly. Everyone has their own understanding and implementation method. One sentence explanation is that if there are enough parameters, it will be executed, if there are not enough parameters, it will be executed. Returns a function with the previous parameters stored until 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]
Copy after login

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 continues to return the function. Otherwise execute.

Anti-shake

According to my understanding, anti-shake means that no matter how many times you trigger it, it will not trigger until a period of time you specify after the last trigger. 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)
 }
}
Copy after login

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. Press space every time Pressing the key will increase the number by 1 to test the 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(&#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>
Copy after login

The two parameters leading and trailing are used to determine whether the start and end are executed. If leading is true, it will be executed every time the space is pressed. If trailing is true, Then each time it ends, the last trigger will be executed. 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)
 }
 }
}
Copy after login

Explain that 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 If it is called after the interval or after the interval, the flag will be reset. You can 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. There is also 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)
 }
 }
}
Copy after login

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
 }
 }
}
Copy after login

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 !== &#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
Copy after login
For basic types, return directly, For reference types, the clone method is called recursively.

Summary

In fact, for the above methods, the general idea is the use of recursion and higher-order functions, including the use of closures. The front-end likes to ask these questions. It is best to Just implement it yourself, which will help your understanding.


Related recommendations:

Various common function definition methods in JavaScript_javascript skills

Summary of js function related knowledge points Share

Explanation of passing by value of js function parameters

The above is the detailed content of Detailed explanation of five common functions in JavaScript. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template