防抖与节流

  • 函数防抖和函数节流都是防止某一时间频繁触发,但是这两者之间的原理却不一样。

  • 函数防抖是某一段时间内只执行一次,而函数节流是间隔时间执行。

防抖

在高频操作下,只识别一次触发(事件的开始时刻或者结束时刻),实现:一般设置一个阈值,在阈值内无论操作多少次,程序只执行一次。

节流

高频操作下,按照规定好的时间为间隔触发一次,等待变化一会在执行程序,避免资源浪费。规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
//模拟一段ajax请求
function ajax(content) {
    console.log('ajax request ' + content)
}
//防抖
function debounce(fun, delay) {
    return function (args) {
        let that = this
        let _args = args
        clearTimeout(fun.id)
        fun.id = setTimeout(function () {
            fun.call(that, _args)
        }, delay)
    }
}

let inputb = document.getElementById('debounce')

let debounceAjax = debounce(ajax, 500)

inputb.addEventListener('keyup', function (e) {
    debounceAjax(e.target.value)
})
节流

高频操作下,按照规定好的时间为间隔触发一次,等待变化一会在执行程序,避免资源浪费。规定在一个单位时间内,只能触发一次函数。如果这个单位时间内触发多次函数,只有一次生效。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
function throttle(fun, delay) {
    let last, deferTimer
    return function (args) {
        let that = this
        let _args = arguments
        let now = +new Date()
        if (last && now < last + delay) {
            clearTimeout(deferTimer)
            deferTimer = setTimeout(function () {
                last = now
                fun.apply(that, _args)
            }, delay)
        }else {
            last = now
            fun.apply(that,_args)
        }
    }
}

let throttleAjax = throttle(ajax, 1000)

let inputc = document.getElementById('throttle')
inputc.addEventListener('keyup', function(e) {
    throttleAjax(e.target.value)
})

对象

对象计算比较:

对象计算时首先查找有没有Symbol.toPrimiative属性,如果有,根据此属性方法的返回值来计算;Symbol.toPrimiativevalueOftoString顺序选择;

如果是字符串连接操作,toString的优先级比valueOf高;条件比较则相反。

解构赋值:

原则:看右侧数据,如果是对象,需要保证赋值对象的key相同,如果是数组,名称随意,左右类型相同。如果多个引用类型的名称,采用起别名的方式。

属性管理:

属性检查:hasOwnProperty 用来检查指定名称是否为当前对象的私有属性in 关键字可以检查共有属性,先私有后公有,在私有属性中没有找到会通过__proto__原型链向下去查找,如果查到最后还没有返回false ,找到返回true

实现检查当前属性是否为共有:

1
console.log(!obj.hasOwnProperty('name') && ('name' in obj));

公有属性(原型或原型链上的)和私有属性(构造方法中)

获取属性名

Object.keys()Object.getOwnPropertyNames():获取对象中所有非Symbol类型的私有属性方法,以数组返回;Object.getOwnPropertySymbols():只获取Symbol的私有属性方法,以数组返回;Object.definePropertie({},'aa',{enumerable:false}):设置属性不可枚举,循环不可以读出,不可以直接被调用,起到一个保护作用。使用for…in…可以迭代原型链中所有可枚举的属性。

禁止向对象添加属性

Object.preventExtensions(obj):禁止向对象添加属性,对原有属性可以修改。严格模式下,设置禁止添加属性,但程序中存在添加代码,会报错,后续代码不执行。

冻结对象

Object.freeze(obj):冻结后的对象不可修改,—将对象定义为一个常量。严格模式下,对已经冻结的对象修改和添加属性会报错,后续代码不执行;非严格模式下,没有效果不报错。可以通过Object.isFrozen(obj)检查当前对象是否为冻结对象。

获取器与修改器
对象属性私有化
浅拷贝与深拷贝