JS- 3 questions pavement week (the first week)

量变产生质变

Foreword

  工作两年多,作为一个前端,越来越感觉到知识储备匮乏,遇到问题百度后记忆也不会深刻,遂打算写这个博客,不只是为了应对面试题,更重要的是能在自己当前能理解的深度上去分析面试题中所涉及到的知识。

Why write key component in the list 1. Write React / Vue project, what is its role?

The official described the document vue follows: Key special properties mainly used in virtual DOM algorithm Vue, the identification VNodes when comparing the old and new nodes . If no key, Vue will minimize the use of a dynamic element and possible try to repair / re-use the same algorithm type element. Using the key, it will rearrange the order of the elements based on a change of key, and the key will remove the element does not exist. The child has the same parent element must have a unique key. Duplicate key will cause rendering errors.

React official described the document as follows: Key help React to identify which elements of change, such as being added or deleted. So you should have a defined identity to each element in the array. An element key preferably is a unique string that has this element in the list. Usually, we use data from key vue and react as the id of the element are based diff algorithm to compare the old and new virtual nodes to update nodes. In vue of diff function. ( First look at the diff algorithm it )

The key value plus any difference and without it

Without binding key, and in a simple traversal template circumstances, lead to a faster comparison of old and new virtual node, the node will reuse. And this multiplexing is multiplexed in situ a duck type multiplexing debate. The following is a simple example:

    <div id="app">
        <div v-for="i in dataList">{{ i }}</div>
    </div>
复制代码
    var vm = new Vue({
      el: '#app',
      data: {
        dataList: [1, 2, 3, 4, 5]
      }
    })
复制代码

v-for content will generate the following array of dom nodes, each node we give an identity marker id:

    [
        '<div>1</div>', // id: A
        '<div>2</div>', // id:  B
        '<div>3</div>', // id:  C
        '<div>4</div>', // id:  D
        '<div>5</div>'  // id:  E
    ]
复制代码

We do different operations on dataList

  1. DataList change data, the position of the replacement data, the comparison data change
    vm.dataList = [4, 1, 3, 5, 2] // 数据位置替换

 // 没有key的情况, 节点位置不变,但是节点innerText内容更新了
  [
    '<div>4</div>', // id: A
    '<div>1</div>', // id:  B
    '<div>3</div>', // id:  C
    '<div>5</div>', // id:  D
    '<div>2</div>'  // id:  E
  ]

  // 有key的情况,dom节点位置进行了交换,但是内容没有更新
  // <div v-for="i in dataList" :key='i'>{{ i }}</div>
  [
    '<div>4</div>', // id: D
    '<div>1</div>', // id:  A
    '<div>3</div>', // id:  C
    '<div>5</div>', // id:  E
    '<div>2</div>'  // id:  B
  ]
复制代码
  1. Additions and deletions to the list of items dataList
    vm.dataList = [3, 4, 5, 6, 7] // 数据进行增删

  // 1. 没有key的情况, 节点位置不变,内容也更新了
  [
    '<div>3</div>', // id: A
    '<div>4</div>', // id:  B
    '<div>5</div>', // id:  C
    '<div>6</div>', // id:  D
    '<div>7</div>'  // id:  E
  ]

  // 2. 有key的情况, 节点删除了 A, B 节点,新增了 F, G 节点
  // <div v-for="i in dataList" :key='i'>{{ i }}</div>
  [
    '<div>3</div>', // id: C
    '<div>4</div>', // id:  D
    '<div>5</div>', // id:  E
    '<div>6</div>', // id:  F
    '<div>7</div>'  // id:  G
  ]
复制代码

  From the above point of view, without a key, and using a simple template, based on this premise, can be more effectively multiplexing nodes, diff is run without a speed faster key, because with the key deletions node in lossy Time. This is the default mode vue document said. But this is not the key role, but the key is not the case in situ multiplex nodes can improve performance.

  However, this model will bring some hidden side effects, such as the transition may not produce the effect, or, in some nodes have binding data (forms) state, there will be dislocation state. VUE document also shows that the default mode is effective, but does not depend only apply to the temporary DOM subassembly state or state (e.g.: form input values) of the list rendered output

  For example, a news list, click on the list of items to be marked as "visited", you can switch "Entertainment News" or "social news" Through tab. Without belt key attributes, select the second item and then switch to the "social news", the second "social news" in the state will be selected under the "entertainment news" because the reuse of components here, It retains its previous state. To solve this problem, you can bring items to the list of news id as the only key, so each will completely replace all components when rendering the list so that it has the correct state.

But what is key is the role?

key是给每一个vnode的唯一id,可以依靠key,更准确,更快的拿到oldVnode中对应的vnode节点。

  1. more acurrate

Because the key is not in place with multiplexing, the situation in ameNode function a.key === b.key contrast in place to avoid reuse. It will be more accurate.

  1. Faster

To obtain a corresponding node, traversal is faster than using a unique key of the subject map generation.

Comparison of loop traversal method 2. js

查了一下迭代和遍历的区别,然后找到了下面这段解释

  • Loop (Loop), refers to the condition is met, the same code is repeatedly performed. For example, while, for, do while statement.
  • Iteration (iterate), refers to each one by one in a certain order to access the list. For example, for the statement.
  • Traversing (Traversal), refers to the access tree structure according to certain rules in each node, and each node is visited only once.
  • Recursion (recursion), refers to a function call to continue their behavior. For example, the output programmatically famous Fibonacci sequence.

Well, I do get down to business

  1. forEach is to let each do one event in the array, the array will change the original
   var arr = [{a: 1}, {a: 2}, {a: 3}]
    arr.forEach((item) => {
    	item.a = 12
    })
    console.log(arr)	// [{a: 12}, {a: 12}, {a: 12}]
复制代码
  1. map is to make the array by some calculations, generate a new array does not change the original array
    var arr = [1, 2, 3]
    var newArr = arr.map((item, index) => {
        return item * 2
    })
    console.log(arr)        // [1, 2, 3]
    console.log(newArr)     // [2, 4, 6]
复制代码
  1. filter is to filter out the array of items eligible to return to the new array does not change the original array
    var arr = [1, 2, 3]
    var newArr = arr.filter((item, index) => {
        return item > 1
    })
    console.log(arr)        // [1, 2, 3]
    console.log(newArr)     // [2, 3]
复制代码
  1. reduce is to make the array antecedent and do some kind of calculation items, and returns the accumulated value
    var arr = [1, 2, 3]
    var res = arr.reduce((prev, next) => {
        return prev*2 + next
    })
    console.log(arr)        // [1, 2, 3]
    console.log(res)        // 1*2 + 2 + 2*2 + 3 = 11
复制代码
  1. for-in object is to traverse the enumerable properties, for-in will inherit the properties of the object will traverse the chain again, it will take more time.
    var obj = {
        name: 'z',
        age: 1,
        do: function() {
            console.log('something')
        }
    }
    for(var key in obj) {
        console.log(key)    // name -> age -> do
    }
复制代码
  1. for-of iteration statement can only traverse data objects
    var arr = [{
        name: 'z',
        do: function() {
            console.log('something')
        }},
        '2',
        3
    ]
    for(item of arr) {
        console.log(item)	// {name: 'z', do: f} -> '2' -> 3
    }
复制代码

Here for example is not a loop, and there are some methods evey (these two methods are not entirely array operation), various cyclic speed is different, the following is sorted by speed

for > for-of > forEach > filter > map > for-in

But which fast and which should be used, and should not be equated.

If you need to map array to another array according to certain rules, you should use map.

If you need a simple traversal using forEach or for of.

If you need to iterators to traverse, with for of.

If you need to filter out the eligible items, with the filter.

If you follow the rules need to be mapped to the new array, and then filtered according to the conditions, then use a map plus a filter. Do not worry this will slow you point the amount of data that the browser does not care.

3. The anti-shake and the throttle

  • Shake
// 防抖:在事件被触发n秒后再执行回调,如果在这n秒内又被触发,则重新计时。
    
    function debounce (fn, delay) {
        let timer
        return function (...arg) {
        // 如果执行期间再次触发,则清空,重新执行
            if (timer) clearTimeout(timer)
            timer = setTimeout(() => {
                fn.apply(this, arg)
            }, delay)
        }
    }
    
    // 需要执行的函数
    function say(context) {
        console.time()
        console.log('hi:'+ context + ' time: ' +  new Date())
        console.timeEnd()
    }
    
    var input = document.querySelector('#input')
    
    var debounceFn = debounce(say, 1000)
    
    input.addEventListener('keyup',  (e) => {
      debounceFn(e.target.value)
    })
复制代码

防抖就像技能点,按一次施放后就进入冷却时间,在冷却时间内再次点按则会重置冷却时间

  • Throttling
    // 节流:规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效
     function throttle(fn, threshhold) {
        var timeout
        var start = +new Date;
        var threshhold = threshhold || 160 // 不给定间隔时间则取默认值
        return function () {
    
          var that = this, args = arguments, curr = +new Date()
    
          clearTimeout(timeout)//总是干掉事件回调
          // 如果当前时间 - 开始时间 >= 间隔时间
          if (curr - start >= threshhold) {
            console.log("now = ", curr,'time = ', curr - start)
            fn.apply(that, args) //只执行一部分方法,这些方法是在某个时间段内执行一次
            start = curr // 重置开始时间
          } else {
            //让方法在脱离事件后也能执行一次
            timeout = setTimeout(function () {
              console.log('else = ', curr,'time = ', curr - start)
              fn.apply(that, args)
            }, threshhold);
          }
        }
      }
      var mousemove = throttle(function (e) {
        console.log(e.pageX, e.pageY)
      }, 2000);
    
    // 绑定监听
    document.querySelector("#panel").addEventListener('mousemove', mousemove);
复制代码

operation result

节流就像水坝,虽然不能让水不流,但是可以减缓水流的速度

to sum up

  函数防抖和函数节流都是防止某一时间频繁触发,函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

Scenarios

- debounce
    - search搜索联想,用户在不断输入值时,用防抖来节约请求资源。
    - window触发resize的时候,不断的调整浏览器窗口大小会不断的触发这个事件,用防抖来让其只触发一次
- throttle
    - 鼠标不断点击触发,mousedown(单位时间内只触发一次)
    - 监听滚动事件,比如是否滑到底部自动加载更多,用throttle来判断。
复制代码

Reproduced in: https: //juejin.im/post/5cee323af265da1b6f435760

Guess you like

Origin blog.csdn.net/weixin_34085658/article/details/91478944