当前位置:网站首页>深拷贝 事件总线
深拷贝 事件总线
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);
边栏推荐
- [geek challenge 2019] upload
- CDA数据分析——AARRR增长模型的介绍、使用
- 浅谈sklearn中的数据预处理
- 5g era, learning audio and video development, a super hot audio and video advanced development and learning classic
- Maximum profit of jz63 shares
- [QT] Qt development environment installation (QT version 5.14.2 | QT download | QT installation)
- 高性能纠删码编码
- Test shift left and right
- Use sqoop to export ads layer data to MySQL
- The blink code based on Arduino and esp8266 runs successfully (including error analysis)
猜你喜欢
MySQL indexes and transactions
arcgis js 4.x 地图中加入图片
kubenetes中port、targetPort、nodePort、containerPort的区别与联系
Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement
Use sqoop to export ads layer data to MySQL
基于Arduino和ESP8266的连接手机热点实验(成功)
分布式机器学习框架与高维实时推荐系统
Initial JDBC programming
Jenkins user rights management
Find the common ancestor of any two numbers in a binary tree
随机推荐
Leetcode14 最长公共前缀
LeetCode—<动态规划专项>剑指 Offer 19、49、60
The blink code based on Arduino and esp8266 runs successfully (including error analysis)
(C language) input a line of characters and count the number of English letters, spaces, numbers and other characters.
使用Sqoop把ADS层数据导出到MySQL
Leetcode922 sort array by parity II
Pytorch builds LSTM to realize clothing classification (fashionmnist)
Codeforces 771-div2 C (trouble, permutation is not very good)
MySQL与PostgreSQL抓取慢sql的方法
Day12 control flow if switch while do While guessing numbers game
JZ63 股票的最大利润
LeetCode—剑指 Offer 59 - I、59 - II
Docker-compose配置Mysql,Redis,MongoDB
Jenkins用户权限管理
Leetcode122 买卖股票的最佳时机 II
The second composition template of postgraduate entrance examination English / chart composition, English chart composition is enough
深入理解P-R曲线、ROC与AUC
CDH存在隐患 : 该角色的进程使用的交换内存为xx兆字节。警告阈值:200字节
Error in kubeadm join: [error port-10250]: port 10250 is in use [error fileavailable--etc kubernetes PKI
CDA数据分析——AARRR增长模型的介绍、使用