日报_30

108 阅读3分钟

2020年6月2日 星期二

Don't spend another minute being angry about yesterday.


这两天主要就是对js原生的方法进行了一个复习,今天学习了call,apply和bind;

apply和call都是为了改变某个函数运行时的上下文而存在的(就是为了改变函数内部this的指向);
bind()–也是改变函数体内this的指向;
bind会创建一个新函数,称为绑定函数,当调用这个函数的时候,绑定函数会以创建它时传入bind
()方法的第一个参数作为this,传入bind()方法的第二个及以后的参数加上绑定函数运行时本
身的参数按照顺序作为原函数的参数来调用原函数;

bind与apply、call最大的区别就是:bind不会立即调用,其他两个会立即调用

三个的使用区别:

都是用来改变函数的this对象的指向的;
第一个参数都是this要指向的对象;
都可以利用后续参数传参;
bind是返回对应函数,便于稍后调用,apply、call是立即调用;

总结:

当我们使用一个函数需要改变this指向的时候才会用到call`apply`bind
如果你要传递的参数不多,则可以使用fn.call(thisObj, arg1, arg2 ...)
如果你要传递的参数很多,则可以用数组将参数整理好调用fn.apply(thisObj, [arg1, arg2 ...])
如果你想生成一个新的函数长期绑定某个函数给某个对象使用,则可以使用const newFn = fn.bind(thisObj); newFn(arg1, arg2...)

参考: segmentfault.com/a/119000001…

防抖和节流

我们在前端开发的过程中,我们经常会需要绑定一些持续触发的事件,如 resize、scroll、mousemove但有些时候我们并不希望在事件持续触发的过程中那么频繁地去执行函数。 通常这种情况下我们怎么去解决的呢?

一般来讲,防抖和节流是比较好的解决方案。

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        #content {
            height: 150px;
            line-height: 150px;
            text-align: center;
            color: #fff;
            background-color: #ccc;
            font-size: 80px;
        }
    </style>
</head>

<body>
    <div id="content"></div>
</body>

</html>
<script>
    let num = 1;
    let content = document.getElementById('content');
    //div 元素绑定了 mousemove 事件,当鼠标在
    // div(灰色)区域中移动的时候会持续地去触发该事件导致频繁执行函数。
    function count() {
        content.innerHTML = num++;
    };
    content.onmousemove = count;

</script>
</script>

那什么是防抖呢?

所谓防抖,就是指触发事件后在 n 秒内函数只能执行一次,如果在 n
秒内又触发了事件,则会重新计算函数执行时间。
//  非立即执行函数
        //非立即执行版的意思是触发事件后函数不会立即执行,而是在 n 秒后执行,如果在 n
        //秒内又触发了事件,则会重新计算函数执行时间。
function debounce(func, wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);
        
        timeout = setTimeout(() => {
            func.apply(context, args)
        }, wait);
    }
}
                /* 立即执行 */
                    //立即执行版的意思是触发事件后函数会立即执行,然后 n
                    //秒内不触发事件才能继续执行函数的效果。
function debounce(func,wait) {
    let timeout;
    return function () {
        let context = this;
        let args = arguments;

        if (timeout) clearTimeout(timeout);

        let callNow = !timeout;
        timeout = setTimeout(() => {
            timeout = null;
        }, wait)

        if (callNow) func.apply(context, args)
    }
}

节流

所谓节流,就是指连续触发事件但是在 n 秒中只执行一次函数。节流会稀释函数的执行频率。
/**
 * @desc 函数节流
 * @param func 函数
 * @param wait 延迟执行毫秒数
 * @param type 1 表时间戳版,2 表定时器版
 */
function throttle(func, wait ,type) {
    if(type===1){
        let previous = 0;
    }else if(type===2){
        let timeout;
    }
    return function() {
        let context = this;
        let args = arguments;
        if(type===1){
            let now = Date.now();

            if (now - previous > wait) {
                func.apply(context, args);
                previous = now;
            }
        }else if(type===2){
            if (!timeout) {
                timeout = setTimeout(() => {
                    timeout = null;
                    func.apply(context, args)
                }, wait)
            }
        }
    }
}