当前位置:网站首页>深拷贝 事件总线
深拷贝 事件总线
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);
边栏推荐
- 单指令多数据SIMD的SSE/AVX指令集和API
- 还不会安装WSL 2?看这一篇文章就够了
- Error in kubeadm join: [error port-10250]: port 10250 is in use [error fileavailable--etc kubernetes PKI
- Fastdateformat why thread safe
- CPU指令集介绍
- 记录一下MySql update会锁定哪些范围的数据
- 深入理解P-R曲线、ROC与AUC
- drools中then部分的写法
- Go learning notes - multithreading
- Le tutoriel F - String le plus facile à comprendre de l'histoire.
猜你喜欢

AAAI 2022 | Peking University & Ali Dharma Institute: pruning and compression of pre training language model based on comparative learning

Jenkins user rights management

Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement
![[QT] Qt development environment installation (QT version 5.14.2 | QT download | QT installation)](/img/18/f0c9ef6250a717f8e66c95da4de08c.jpg)
[QT] Qt development environment installation (QT version 5.14.2 | QT download | QT installation)

分布式机器学习框架与高维实时推荐系统

Mysql database foundation

HR wonderful dividing line

PyTorch nn. Full analysis of RNN parameters

Natural language processing series (I) -- RNN Foundation

Find the common ancestor of any two numbers in a binary tree
随机推荐
Jenkins voucher management
高性能纠删码编码
Writing method of then part in drools
分布式机器学习框架与高维实时推荐系统
高德地图测试用例
刷题---二叉树--2
Leetcode922 按奇偶排序数组 II
The second composition template of postgraduate entrance examination English / chart composition, English chart composition is enough
中国交通标志检测数据集
Drools executes string rules or executes a rule file
[I'm a mound pytorch tutorial] learning notes
甜心教主:王心凌
jenkins 凭证管理
Find the factorial of a positive integer within 16, that is, the class of n (0= < n < =16). Enter 1111 to exit.
Jenkins user rights management
Sweetheart leader: Wang Xinling
MSI announced that its motherboard products will cancel all paper accessories
ES集群中节点与分片的区别
Calculate the maximum path sum of binary tree
(C language) octal conversion decimal