系列文章
前端八股文-手写new、bind、call、apply的三两事
深拷贝
function deep(obj) {
if (!obj || typeof obj !== 'object') {
return obj;
}
let objClone = Array.isArray(obj) ? [] : {};
if (obj && typeof obj === 'object') {
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (obj[key] && typeof obj[key] === 'object') {
objClone[key] = deep(obj[key])
} else {
objClone[key] = obj[key]
}
}
}
}
return objClone
}
对象扁平化({dto: {name:1}})=> {dto: {name:1},dtoName: 1}
function flatObj(obj, keyName) {
if (!obj || typeof obj !== 'object') {
return obj;
}
let finallyData = {}
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
const newKeyName = keyName ? keyName + key.substring(0, 1).toUpperCase() + key.substring(1) : key
if (obj[key] && typeof obj[key] !== 'object' || Array.isArray(obj[key]) || Object.keys(obj[key]).length === 0) {
finallyData[newKeyName] = obj[key]
} else {
finallyData = Object.assign({}, finallyData, flatObj(obj[key], newKeyName))
}
}
}
return finallyData
}
eventbus(简单的发布订阅模式)
class EventBus {
constructor() {
EventBus.EventStore = {
$uid: 0
};
}
on(type, handler) {
let cache = EventBus.EventStore[type] || (EventBus.EventStore[type] = {});
handler.$uid = handler.$uid || EventBus.EventStore.$uid++;
cache[handler.$uid] = handler;
}
emit(type, ...param) {
let cache = EventBus.EventStore[type],
key,
tmp;
if (!cache) return;
for (key in cache) {
tmp = cache[key];
tmp.call(this, ...param);
}
}
off(type, handler) {
let counter = 0,
cache = EventBus.EventStore[type];
if (handler == null) {
if (!cache) return true;
return !!EventBus.EventStore[type] && (delete EventBus.EventStore[type]);
} else {
!!EventBus.EventStore[type] && (delete EventBus.EventStore[type][handler.$uid]);
}
for (const key in cache) {
counter++;
}
return !counter && (delete EventBus.EventStore[type]);
}
}
节流(原理:在规定时间内只触发一次)
function throttle (fn, delay) {
// 利用闭包保存时间
let prev = Date.now()
return function () {
let context = this
let arg = [...arguments]
let now = Date.now()
if (now - prev >= delay) {
fn.apply(context, arg)
prev = Date.now()
}
}
}
防抖(原理:在规定时间内未触发第二次,则执行)
function debounce(fn, delay) {
let timer = null;
return function() {
let args = [...arguments];
let context = this;
clearTimeout(timer);
timer = setTimeout(() =>{
fn.apply(context, arg)
}, delay)
}
}
懒加载
let imgs = document.querySelectorAll('img')
// 可视区高度
let clientHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight
function lazyLoad () {
// 滚动卷去的高度
let scrollTop = window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop
for (let i = 0; i < imgs.length; i ++) {
// 图片在可视区冒出的高度
let x = clientHeight + scrollTop - imgs[i].offsetTop
// 图片在可视区内
if (x > 0 && x < clientHeight+imgs[i].height) {
imgs[i].src = imgs[i].getAttribute('data')
}
}
}
// addEventListener('scroll', lazyLoad) or setInterval(lazyLoad, 1000)