防抖和节流
防抖
函数防抖 (防抖)
短时间快速触发同一个事件
每一次都用下一次干掉上一次,永远执行最后一次
// 第一步
// 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>