cloneTarget[prop] = target[prop];
}
}
return cloneTarget;
} else {
return target;
}
}
2.手动实现一个深克隆(简易版)
深克隆: 层层拷贝对象或数组的每一层内容
function deepClone(target) {
if (target === null) return null;
if (typeof target !== ‘object’) return target;
const cloneTarget = Array.isArray(target) ? [] : {};
for (let prop in target) {
if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = deepClone(target[prop]);
}
}
return cloneTarget;
}
3.手动实现一个深克隆(考虑日期/正则等特殊对象 和 解决循环引用情况)
const isObject = (target) => (typeof target === ‘object’ || typeof target === ‘function’) && target !== null;
function deepClone (target, map = new Map()) {
/ 《大厂前端面试题解析+Web核心总结学习笔记+企业项目实战源码+最新高清讲解视频》无偿开源 徽信搜索公众号【编程进阶路】 / 先判断该引用类型是否被 拷贝过
if (map.get(target)) {
return target;
}
// 获取当前值的构造函数:获取它的类型
let constructor = target.constructor;
// 检测当前对象target是否与 正则、日期格式对象匹配
if (/^(RegExp|Date)$/i.test(constructor.name)){
return new constructor(target); // 创建一个新的特殊对象(正则类/日期类)的实例
}
if (isObject(target)) {
map.set(target, true); // 为循环引用的对象做标记
const cloneTarget = Array.isArray(target) ? [] : {};
for (let prop in target) {
if (target.hasOwnProperty(prop)) {
cloneTarget[prop] = deepClone(target[prop], map);
}
}
return cloneTarget;
} else {
return target;
}
}
4.手动实现instanceOf的机制
思路:
步骤1: 先取得当前类的原型,当前实例对象的原型链
步骤2: 一直循环(执行原型链的查找机制)
-
取得当前实例对象原型链的原型链(
proto = proto.__proto__
,沿着原型链一直向上查找) -
如果 当前实例的原型链
__proto__
上找到了当前类的原型prototype
,则返回true
-
如果 一直找到
Object.prototype.__proto__ == null
,Object的基类(null)上面都没找到,则返回 false
function _instanceof (instanceObject, classFunc) {
let classFunc = classFunc.prototype; // 取得当前类的原型
let proto = instanceObject.proto; // 取得当前实例对象的原型链
while (true) {
if (proto === null) { // 找到了 Object的基类 Object.prototype.proto
return false;
};
if (proto === classFunc) { // 在当前实例对象的原型链上,找到了当前类
return true;
}
proto = proto.proto; // 沿着原型链__ptoto__一层一层向上查找
}
}
优化版 (处理兼容问题)
Object.getPrototypeOf:用来获取某个实例对象的原型(内部[[prototype]]属性的值,包含proto属性)
function _instanceof (instanceObject, classFunc) {
let classFunc = classFunc.prototype; // 取得当前类的原型
let proto = Object.getPrototypeOf(instanceObject); // 取得当前实例对象的原型链上的属性
while (true) {
if (proto === null) { // 找到了 Object的基类 Object.prototype.proto
return false;
};
if (proto === classFunc) { // 在当前实例对象的原型链上,找到了当前类
return true;
}
proto = Object.getPrototypeOf(proto); // 沿着原型链__ptoto__一层一层向上查找
}
}
5. 手动实现防抖函数
实现函数的防抖(目的是频繁触发中只执行一次)
以最后一次触发为标准
/**
* 实现函数的防抖(目的是频繁触发中只执行一次)
* @param {*} func 需要执行的函数
* @param {*} wait 检测防抖的间隔频率
* @param {*} immediate 是否是立即执行 True:第一次,默认False:最后一次
* @return {可被调用执行的函数}
*/
function debounce(func, wati = 500, immediate = false) {
let timer = null
return function anonymous(… params) {
clearTimeout(timer)
timer = setTimeout(_ => {
// 在下一个500ms 执行