Research on source code of underscore.js (7)

Overview

I have wanted to study the underscore source code for a long time. Although the underscore.js library is a bit outdated, I still want to learn about the library's architecture, functional programming and the writing of common methods, but there is nothing else to study. , so let's end the wish to study the underscore source code.

underscore.js source code research (1)
underscore.js source code research (2)
underscore.js source code research (3)
underscore.js source code research (4)
underscore.js source code research (5)
underscore.js source code research (6)
underscore. js source code research (7)
underscore.js source code research (8)

References: official notes of underscore.js , undersercore source code analysis , undersercore source code analysis segmentfault

Function throttling and debounce

Sometimes there is such a situation, that is, a button is designed in the front section. Every time the button is clicked, an http request will be sent to the server. If a malicious user uses the code to click 100 times in 1 second, it will cause unimaginable pressure on the server. , which may crash the server.

There is also such a situation, there is an event listener on the front end, which needs to monitor the position of the mouse movement, and then execute a callback function, then every time the mouse is dragged, the callback function will be executed. If the callback function causes the DOM to change, it will cause Reflow and redraw seriously affect the performance of the browser.

At this time, function throttling and debounce can be used.

function throttling

Function throttling is to limit the number of times a function is executed within a certain period of time .

Before discussing function throttling, let's talk about function exclusive : if the function is executing, it is not allowed to execute the function again. The mechanism is to mark whether the function is executing by setting a flag.

var isQuerying = false;

//complete是一个回调函数
var sendQuery = function(complete) {
    if(isQuerying) {
        //使用return来中断函数的执行
        return;
    }
    isQuerying = true;
    // 我们模拟一个耗时操作(回调)
    setTimeout(function(){
        complete && complete();
    },2000);
}

var complete = function() {
   // 在回调中, 我们刷新标记量
   isQuerying = false;
}

$("#queryBtn").click(function(){sendQuery(complete);});

Let's take a look at function throttling: limit the number of function executions within a certain period of time , the excess times will be combined into one and delay the execution of waiting seconds (throttling).

//cb是回调函数,waiting是在waiting时间段内只能执行一次
var throttle = function(cb, waiting) {
    var timeout;
    var previous = 0;
    var throttled = function() {
        var now = (new Date()).getTime();
        if(!previous) previous = now;
        var remaining = waiting - (now - previous);
        //如果在时间内已经执行过
        if(remaining >= 0) {
            //如果之前延迟过一个函数那就清除这个延迟不执行
            if(timeout) {
                clearTimeout(timeout);
                timeout = null;
            }
            //这里延迟函数执行时比如更新previous
            //underscore.js直接把这里独立为一个函数
            //即把原回调函数包裹为一个延迟执行函数
            timeout = setTimeout(function() {
                var now = (new Date()).getTime();
                previous = now;
                cb();
            }, waiting);
        } else {
            previous = now;
            cb();
        }
    }
    return throttled;
}

Note: The execution situation here can be studied in depth, and how to execute the redundant times is a problem.

function debounce

Function debounce is to execute a continuous function call for a certain period of time only once.

Here is a good example to illustrate the difference between function throttle and function debounce :

  • Press a button to send AJAX: After adding debounce to click, even if the user keeps clicking the button, it will only be sent once; if it is throttle, it will be sent several times at intervals.
  • Listen to scroll events to determine whether to automatically load more at the bottom of the page: After adding debounce to scroll, it will only be judged whether the bottom of the page is reached after the user stops scrolling; if it is throttle, as long as the page scrolls, it will be judged at intervals.

So the key is to delay the execution of the callback function. If the callback function is called again within the waiting time, the delay time is refreshed (the last delay is canceled and the new delay is executed). The key difference with function throttling is that there is no remaining parameter .

code show as below:

//cb是回调函数,waiting是时间段内,immediate是是否第一次需要立即执行一次
var debounce = function(cb, waiting, immediate) {
    var timeout;
    var debounced = function() {
        if(timeout) clearTimeout(timeout);
        timeout = null;
        //如果需要第一次立即执行一次
        if(immediate && !timeout) cb();
        //无论如何都延迟执行一次
        timeout = setTimeout(cb, waiting);
    }
    return debounced;
}

The test code is as follows:

var debounce = function(cb, waiting, immediate) {
    var timeout;
    var debounced = function() {
        if(timeout) clearTimeout(timeout);
        timeout = null;
        //如果需要第一次立即执行一次
        if(immediate && !timeout) cb();
        //无论如何都延迟执行一次
        timeout = setTimeout(cb, waiting);
    }
    return debounced;
}

function print() {
  console.log('hello world');
}

var debouncedPrint = debounce(print, 1000);

window.onscroll = function() {
  debouncedPrint();
};

Object property and method traversal

We can use Object.prototype.hasOwnProperty to determine whether a property is its own property (method), it will not look for properties (methods) on the prototype chain .

We can also enumerate all the properties (methods) of an object through Object.keys, and it will not look for properties (methods) on the prototype chain .

However, in addition to looking for the object's own properties (methods), for in also looks for properties (methods) on the prototype chain.

in will look for not only enumerable properties on itself and the prototype, but also non-enumerable properties .

It is worth noting that:

  1. Object.prototype.hasOwnProperty, Object.keys and for in all only look for enumerable properties (methods), not non-enumerable ones, such as the toString method .
  2. If you want to distinguish between attributes and methods, you can add a judgment function isFunction .

Object function

I believe that for most people, the Object function is only used in new. In fact, the Object function can also be used alone:

var obj = Object(obj);

Its meaning is:

  • If obj is an object, this object is returned.
  • If obj is undefined or null, return {}.
  • If obj is a primitive value, the primitive value wrapped by the object is returned.

An example is as follows:

console.log(Object({a:2})); //{a: 2}
console.log(Object(null)); //{}
console.log(Object(2)); //{[[PrimitiveValue]]: 2}
console.log(Object(2) + 1); //3

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325215205&siteId=291194637