当前位置:网站首页>深拷贝 事件总线
深拷贝 事件总线
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);
边栏推荐
- Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement
- Those logs in MySQL
- China traffic sign detection data set
- jenkins 凭证管理
- Natural language processing series (I) -- RNN Foundation
- Sparkcontext: error initializing sparkcontext solution
- Sweetheart leader: Wang Xinling
- 基于Arduino和ESP8266的连接手机热点实验(成功)
- lombok常用注解
- conda常用命令汇总
猜你喜欢

drools决策表的简单使用

Is the neural network (pinn) with embedded physical knowledge a pit?

Deep understanding of NN in pytorch Embedding

Record the range of data that MySQL update will lock

mysql索引和事务

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

Applet link generation

Simple use of drools decision table

MSI announced that its motherboard products will cancel all paper accessories

Less than three months after the programmer was hired, the boss wanted to launch the app within one month. If he was dissatisfied, he was dismissed immediately
随机推荐
CDH存在隐患 : 该角色的进程使用的交换内存为xx兆字节。警告阈值:200字节
Input a three digit number and output its single digit, ten digit and hundred digit.
conda常用命令汇总
堆(优先级队列)
Discrimination of the interval of dichotomy question brushing record (Luogu question sheet)
[C language] Yang Hui triangle, customize the number of lines of the triangle
Codeforces 771 div2 B (no one FST, refers to himself)
分布式机器学习框架与高维实时推荐系统
Leetcode topic [array] -540- single element in an ordered array
drools执行指定的规则
二分刷题记录(洛谷题单)区间的甄别
Those logs in MySQL
Multiply LCA (nearest common ancestor)
[geek challenge 2019] upload
Go learning notes - multithreading
Leetcode14 longest public prefix
High performance erasure code coding
LeetCode—剑指 Offer 51. 数组中的逆序对
CPU指令集介绍
(C language) input a line of characters and count the number of English letters, spaces, numbers and other characters.