当前位置:网站首页>深拷贝 事件总线
深拷贝 事件总线
2022-07-02 09:43:00 【大海里没有水】
一、深拷贝
1、JSON.stringify

2、版本1 : 自定义深拷贝 - 基本实现
// 判断一个值是不是对象
function isObject(value) {
const valueType = typeof value;
return value !== null && (valueType === "object" || valueType === "function");
}
function deepClone(originValue) {
// 判断传入的originValue是否是一个对象类型
if (!isObject(originValue)) {
return originValue;
}
const newObject = {
};
for (const key in originValue) {
newObject[key] = deepClone(originValue[key]);
}
return newObject;
}
// 测试代码
const obj = {
name: "chen",
age: 23,
friends: {
name: "zhangsan",
address: {
city: "广州",
},
},
};
const newObj = deepClone(obj);
console.log(newObj === obj);
obj.friends.name = "lisi";
console.log(newObj);
3、版本2 : 自定义深拷贝 - 数组、函数、Symbol、Set、Map拷贝
// 判断一个值是不是对象
function isObject(value) {
const valueType = typeof value;
return value !== null && (valueType === "object" || valueType === "function");
}
function deepClone(originValue) {
// 判断是否是一个Set类型
if (originValue instanceof Set) {
return new Set([...originValue]);
}
// 判断是否是一个Map类型
if (originValue instanceof Map) {
return new Map([...originValue]);
}
// 判断如果是Symbol的value,那么就创建一个新的Symbol
if (typeof originValue === "symbol") {
return Symbol(originValue.description);
}
// 判断函数,函数的直接复用即可,没有必要拷贝,this也是动态绑定的
if (typeof originValue === "function") {
return originValue;
}
// 判断传入的originValue是否是一个对象类型
if (!isObject(originValue)) {
return originValue;
}
// 判断传入的对象是数组,还是普通对象
const newObject = Array.isArray(originValue) ? [] : {
};
for (const key in originValue) {
newObject[key] = deepClone(originValue[key]);
}
// Symbol作为key,for是遍历不出来的
// 对Symbol的key进行特殊的处理
const symbolKeys = Object.getOwnPropertySymbols(originValue);
for (const sKey of symbolKeys) {
newObject[sKey] = deepClone(originValue[sKey]);
}
return newObject;
}
let s1 = Symbol("aaa");
let s2 = Symbol("bbb");
// 测试代码
const obj = {
name: "chen",
age: 23,
friends: {
name: "zhangsan",
address: {
city: "广州",
},
},
hobbies: ["a", "b", "c"],
foo: function () {
console.log("foo");
},
[s1]: "abc",
s2: s2,
set: new Set(["a", "b", "c"]),
map: new Map([
["aaa", "bbb"],
["bbb", "ccc"],
]),
};
const newObj = deepClone(obj);
console.log(newObj === obj);
obj.friends.name = "lisi";
console.log(newObj);
3、版本3 : 自定义深拷贝 - 循环引用的处理
// 判断一个值是不是对象
function isObject(value) {
const valueType = typeof value;
return value !== null && (valueType === "object" || valueType === "function");
}
function deepClone(originValue, map = new WeakMap()) {
// 判断是否是一个Set类型
if (originValue instanceof Set) {
return new Set([...originValue]);
}
// 判断是否是一个Map类型
if (originValue instanceof Map) {
return new Map([...originValue]);
}
// 判断如果是Symbol的value,那么就创建一个新的Symbol
if (typeof originValue === "symbol") {
return Symbol(originValue.description);
}
// 判断函数,函数的直接复用即可,没有必要拷贝,this也是动态绑定的
if (typeof originValue === "function") {
return originValue;
}
// 判断传入的originValue是否是一个对象类型
if (!isObject(originValue)) {
return originValue;
}
if(map.has(originValue)) {
return map.get(originValue)
}
// 判断传入的对象是数组,还是普通对象
const newObject = Array.isArray(originValue) ? [] : {
};
map.set(originValue, newObject);
for (const key in originValue) {
newObject[key] = deepClone(originValue[key], map);
}
// Symbol作为key,for是遍历不出来的
// 对Symbol的key进行特殊的处理
const symbolKeys = Object.getOwnPropertySymbols(originValue);
for (const sKey of symbolKeys) {
newObject[sKey] = deepClone(originValue[sKey], map);
}
return newObject;
}
let s1 = Symbol("aaa");
let s2 = Symbol("bbb");
// 测试代码
const obj = {
name: "chen",
age: 23,
friends: {
name: "zhangsan",
address: {
city: "广州",
},
},
hobbies: ["a", "b", "c"],
foo: function () {
console.log("foo");
},
[s1]: "abc",
s2: s2,
set: new Set(["a", "b", "c"]),
map: new Map([
["aaa", "bbb"],
["bbb", "ccc"],
]),
};
// 存在循环引用问题
obj.info = obj;
const newObj = deepClone(obj);
console.log(newObj === obj);
obj.friends.name = "lisi";
console.log(newObj);
二、事件总线

class MYEventBus {
constructor() {
this.eventBus = {
};
}
on(eventName, eventCallback, thisArg) {
let handlers = this.eventBus[eventName];
if (!handlers) {
handlers = [];
this.eventBus[eventName] = handlers;
}
handlers.push({
eventCallback, thisArg });
}
off(eventName, eventCallback) {
let handlers = this.eventBus[eventName];
if (!handlers) {
return;
}
const newHandlers = [...handlers];
for (let i = 0; i < newHandlers.length; i++) {
const handler = newHandlers[i];
if (handler.eventCallback === eventCallback) {
const index = handlers.indexOf(handler);
handlers.splice(index, 1);
}
}
}
emit(eventName, ...payload) {
const handlers = this.eventBus[eventName];
if (!handlers) {
return;
}
handlers.forEach((handler) => {
handler.eventCallback.apply(handler.thisArg, payload);
});
}
}
const eventBus = new MYEventBus();
// main.js, 监听, 参数:事件名称,跟传递的参数payload
eventBus.on(
"abc",
function (payload) {
console.log("监听abc", this);
},
{
name: "zhangsan" }
);
// 是可以监听多个事件的
const handleCallback = function (payload) {
console.log("监听abc", this);
};
eventBus.on("abc", handleCallback, {
name: "zhangsan" });
// utils.js
eventBus.emit("abc", 123);
// 移除
eventBus.off("abc", handleCallback);
eventBus.emit("abc", 123);
边栏推荐
猜你喜欢

CDA data analysis -- Introduction and use of aarrr growth model

Pytorch builds LSTM to realize clothing classification (fashionmnist)

Small guide for rapid formation of manipulator (VII): description method of position and posture of manipulator

Embedded Software Engineer career planning

Tas (file d'attente prioritaire)

Record the range of data that MySQL update will lock

Jenkins voucher management

寻找二叉树中任意两个数的公共祖先

Distributed machine learning framework and high-dimensional real-time recommendation system

HR wonderful dividing line
随机推荐
初始JDBC 编程
Natural language processing series (I) -- RNN Foundation
测试左移和右移
二分刷题记录(洛谷题单)区间的甄别
Error in kubeadm join: [error port-10250]: port 10250 is in use [error fileavailable--etc kubernetes PKI
Writing method of then part in drools
Differences between nodes and sharding in ES cluster
CDA数据分析——AARRR增长模型的介绍、使用
Fresh, 2022 advanced Android interview must know 100 questions (interview questions + answer analysis)
Go学习笔记—多线程
[C language] Yang Hui triangle, customize the number of lines of the triangle
drools中then部分的写法
【工控老马】西门子PLC Siemens PLC TCP协议详解
[geek challenge 2019] upload
Map和Set
Embedded Software Engineer career planning
Lekao: contents of the provisions on the responsibility of units for fire safety in the fire protection law
CONDA common command summary
史上最易懂的f-string教程,收藏這一篇就够了
Post request body content cannot be retrieved repeatedly