【JavaScript】防抖和节流、数据驱动视图、数据劫持

防抖和节流

防抖

函数防抖 (防抖)
短时间快速触发同一个事件
每一次都用下一次干掉上一次,永远执行最后一次

// 第一步
    // let timer = null
    // inp1.oninput = function () {
    //     clearInterval(timer)
    //     timer = setTimeout(() => {
    //         console.log(this.value);
    //     }, 2000);
    // }

    // 第二步 把变量放在函数里面,不污染全局 写一个闭包
    // inp1.oninput = (function () {
    //     let timer = null
    //     return function () {
    //         clearInterval(timer)
    //         timer = setTimeout(() => {
    //             console.log(this.value);
    //         }, 2000);
    //     }
    // })()

    // 第三步 封装防抖函数
    function debounce(cb = () => { }) {
        let timer = null
        return function () {
            clearInterval(timer)
            timer = setTimeout(() => {
                // console.log(this.value); 
                cb.call(this)// 普通函数调用,this指向不对,
            }, 2000);
        }
    }

    inp1.oninput = debounce(function () {
        console.log(this.value);
    })

节流

节流 (技能cd)
短时间内快速触发同一个事情
第一次执行过程中,不能重复触发, 等到第一次执行完毕后,才可以触发第二次

 // inp1.oninput = function (e) {
    //     console.log(this.value);
    // }

    // 第一步 实现代码
    // let flag = false
    // inp1.oninput = function () {
    //     if (flag) return
    //     flag = true
    //     setTimeout(() => {
    //         console.log(this.value);
    //         flag = false
    //     }, 2000);
    // }

    // 第二步 闭包

    // inp1.oninput = (function () {
    //     let flag = false
    //     return function () {
    //         if (flag) return
    //         flag = true
    //         setTimeout(() => {
    //             console.log(this.value);
    //             flag = false
    //         }, 2000);
    //     }
    // })()


    // 第三步 封装
    function throttle(cb = () => { }) {
        let flag = false
        return function () {
            if (flag) return
            flag = true
            setTimeout(() => {
                cb.call(this)
                flag = false
            }, 2000);
        }
    }
    inp1.oninput = throttle(
        function () {
            console.log(this.value);
        }
    )

数据驱动视图

    数据: 渲染的数据
    视图:  页面结构

    MVVM 框架类型 vue2

    M modal 数据层
    V view   视图层
    VM  viewModel 工具

    Object.defineproperty 静态方法

语法
Object.defineproperty(数据, 属性名, {配置项})
配置项
- value 设置属性名对象的属性值
- writable 设置的属性是否可以修改 true/false(默认)
- enumerable 设置的属性是否可以遍历 true/false (默认)
- configurable 设置的属性是否可以删除 true/false(默认)

        getter setter 不允许和value, writable连用, 连用会报错
        - get 获取的时候可以触发的方法
        - set 设置的时候可以触发的方法
value
    const obj = { name: 'tom' }
    Object.defineProperty(obj, 'age', {
        value: 20
    })
    console.log(obj);
    obj.age = 30
    console.log(obj);

writable

    const obj = { name: 'tom' }
    Object.defineProperty(obj, 'age', {
        value: 20,
        writable: true
    })
    console.log(obj);
    obj.age = 30
    console.log(obj);
enumerable
    const obj = { name: 'tom' }
    Object.defineProperty(obj, 'age', {
        value: 20,
        writable: true,
        enumerable: true
    })
    for (let k in obj) {
        console.log(k, obj[k]);
    }
configurable
    const obj = { name: 'tom' }
    Object.defineProperty(obj, 'age', {
        value: 20,
        writable: true,
        enumerable: true,
        configurable: true
    })
    delete obj.age
    console.log(obj);
get set定义属性
// 
    // const obj = { name: 'tom' }
    // Object.defineProperty(obj, 'age', {
    //     get() {
    //         console.log('get');
    //         return 'xxx' // 当我们设置一个返回值的时候,就表示该属性被设置了值
    //     },
    //     set(val) {
    //         // 可以监听到设置的值
    //         console.log('set', val);
    //     }
    // })
    // obj.age = 19 // 设置的时候,会触发 set方法
    // console.log(obj.age); // 获取的时候, 会触发 get方法
    // console.log(obj);


    // const obj = { name: 'tom' }
    // Object.defineProperty(obj, 'age', {
    //     get() {
    //         console.log('get');
    //         return '小花' // 当我们设置一个返回值的时候,就表示该属性被设置了值
    //     }
    // })
    // console.log(obj);
    // console.log(obj.age);

    const obj = { name: 'tom' }
    let v = null
    Object.defineProperty(obj, 'age', {
        get() {
            return v
        },
        set(val) {
            // 就是通过对象语法设置的值
            console.log(val);
            v = val
        }
    })

    obj.age = 20
    console.log(obj.age);

数据劫持

    - 当访问或者修改对象的某个属性的时候, 通过 getter setter 拦截这个行为,进行额外的操作 
    - 将原始的数据复制一份,通过复制的数据操作原始数据
// 原始数据
    const obj = {
        name: 'tom',
        age: 18
    }

    // 目标数据
    const target = {}
    // 通过数据劫持的方法,把原始数据复制到目标中

    Object.defineProperty(target, 'name', {
        get() {
            return obj.name
        },
        set(val) {
            obj.name = val
            box.innerHTML = `你好, 我叫${target.name} , 我今年${target.age}`
        }
    })

    Object.defineProperty(target, 'age', {
        get() {
            return obj.age
        },
        set(val) {
            obj.age = val
            box.innerHTML = `你好, 我叫${target.name} , 我今年${target.age}`
        }
    })

    // =========================
    box.innerHTML = `你好, 我叫${target.name} , 我今年${target.age}`

    inp1.onchange = function () {
        target.name = this.value
    }
    inp2.onchange = function () {
        target.age = this.value
    }

vue2

<body>
  <div id="app">
    {{ message }} {{age}}
  </div>
  {{ message }}
</body>

<script src="https://cdn.jsdelivr.net/npm/vue@2/dist/vue.js"></script>
<script>
  /*
        vue3 https://cn.vuejs.org/guide/introduction.html
        vue2 https://v2.cn.vuejs.org/
    */
  // app 是 Vue 构造函数实例化的对象
  var app = new Vue({
    // el 是一个容器,只有这个容器里面的代码可以被vue处理
    el: '#app',
    // data 是一个数据集合,放着变量
    data: {
      message: '你好 小花!',
      age: 18,
    },
    mounted() {
      this.message = 'hello'
      this.age = 19
      this.xxx = 'xx'
    }
  })
  // 构造函数的this指向实例化后的新对象 app
</script>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

芒果Cake

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值