当前位置:网站首页>深拷贝 事件总线
深拷贝 事件总线
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);
边栏推荐
- 自然语言处理系列(一)——RNN基础
- Leetcode14 最长公共前缀
- Distributed machine learning framework and high-dimensional real-time recommendation system
- Leetcode209 subarray with the smallest length
- Deep understanding of NN in pytorch Embedding
- 全链路压测
- [C language] convert decimal numbers to binary numbers
- Map and set
- Embedded Software Engineer career planning
- 寻找二叉树中任意两个数的公共祖先
猜你喜欢
AI中台技术调研
CONDA common command summary
[C language] convert decimal numbers to binary numbers
Initial JDBC programming
Addition, deletion, modification and query of MySQL table (Advanced)
刷题---二叉树--2
Differences between nodes and sharding in ES cluster
自然语言处理系列(一)——RNN基础
Sparkcontext: error initializing sparkcontext solution
高性能纠删码编码
随机推荐
[geek challenge 2019] upload
堆(优先级队列)
arcgis js 4.x 地图中加入图片
FastDateFormat为什么线程安全
Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement
Go learning notes - multithreading
There is a hidden danger in CDH: the exchange memory used by the process of this role is XX megabytes. Warning threshold: 200 bytes
Drools executes string rules or executes a rule file
Leetcode739 每日温度
输入一个三位的数字,输出它的个位数,十位数、百位数。
Initial JDBC programming
SCM power supply
(C language) octal conversion decimal
Sweetheart leader: Wang Xinling
Jenkins user rights management
LeetCode—剑指 Offer 37、38
Simple use of drools decision table
[I'm a mound pytorch tutorial] learning notes
(C language) input a line of characters and count the number of English letters, spaces, numbers and other characters.
单指令多数据SIMD的SSE/AVX指令集和API