🙏废话不多说系列,直接开整🙏
1. 只调用一次函数 ♥
const once = fn => {
let called = false
return function () {
if(!called) {
called = true
fn.apply(this, arguments)
}
}
};
用法:(可以用于防抖)
const startApp = function(event) {
console.log(this, event); // document.body, MouseEvent
};
document.body.addEventListener('click', once(startApp)); // 只执行一次startApp
整体示例
<script>
const once = fn => {
let called = false
return function() {
if (!called) {
called = true
fn.apply(this, arguments)
}
}
};
const startApp = function(event) {
console.log("测试按钮,整个页面的声明周期只是触发一次");
console.log(this, event); // document.body, MouseEvent
};
document.body.addEventListener('click', once(startApp));
document.querySelector("#"+"btnDemo").addEventListener('click', once(startApp));
</script>
<body>
<button id="btnDemo">测试按钮</button>
</body>
2. 以 键 的路径扁平化对象 flattenObject ♥
使用递归。
- 利用Object.keys(obj)联合Array.prototype.reduce(),以每片叶子节点转换为扁平的路径节点。
- 如果键的值是一个对象,则函数使用调用适当的自身prefix以创建路径Object.assign()。
- 否则,它将适当的前缀键值对添加到累加器对象。
- prefix除非您希望每个键都有一个前缀,否则应始终省略第二个参数。
const flattenObject = (obj, prefix = '') =>
Object.keys(obj).reduce((acc, k) => {
const pre = prefix.length ? prefix + '.' : '';
if (typeof obj[k] === 'object') Object.assign(acc, flattenObject(obj[k], pre + k));
else acc[pre + k] = obj[k];
return acc;
}, {});
flattenObject({ a: { b: { c: 1 } }, d: 1 }); // { 'a.b.c': 1, d: 1 }
3. 以 键 的路径展开对象 unflattenObject ♥
与上面的相反,展开对象。(用处:这个的用途,在做Tree组件或复杂表单时取值非常舒服。)
const unflattenObject = obj =>
Object.keys(obj).reduce((acc, k) => {
if (k.indexOf('.') !== -1) {
const keys = k.split('.');
Object.assign(acc,
JSON.parse(
'{' + keys.map((v, i) => (i !== keys.length - 1 ? `"${v}":{` : `"${v}":`)).join('') + obj[k] + '}'
.repeat(keys.length))
);
} else acc[k] = obj[k];
return acc;
}, {});
unflattenObject({ 'a.b.c': 1, d: 1 }); // { a: { b: { c: 1 } }, d: 1 }
🙏至此,非常感谢阅读🙏