当前位置:网站首页>深拷貝 事件總線
深拷貝 事件總線
2022-07-02 12:27: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);
边栏推荐
- The differences and relationships among port, targetport, nodeport and containerport in kubenetes
- Jenkins user rights management
- 上传文件时,服务器报错:IOFileUploadException: Processing of multipart/form-data request failed. 设备上没有空间
- Programmers can't find jobs after the age of 35? After reading this article, you may be able to find the answer
- Those logs in MySQL
- 使用Sqoop把ADS层数据导出到MySQL
- This "little routine" is set on the dough cake of instant noodles. No wonder programmers are always hungry
- Leetcode14 最长公共前缀
- 排序---
- 基于Arduino和ESP8266的Blink代码运行成功(包含错误分析)
猜你喜欢

Initial JDBC programming

PyTorch nn. Full analysis of RNN parameters

MySQL indexes and transactions

Mysql database foundation

Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement

kubenetes中port、targetPort、nodePort、containerPort的区别与联系

使用Sqoop把ADS层数据导出到MySQL

记录一下MySql update会锁定哪些范围的数据

Map and set

Natural language processing series (I) -- RNN Foundation
随机推荐
Multiply LCA (nearest common ancestor)
刷题---二叉树--2
Natural language processing series (I) -- RNN Foundation
Leetcode - Sword finger offer 37, 38
Adding database driver to sqoop of cdh6
Mysql database foundation
Tas (file d'attente prioritaire)
Leetcode209 长度最小的子数组
lombok常用注解
Sweetheart leader: Wang Xinling
SparkContext: Error initializing SparkContext解决方法
The second composition template of postgraduate entrance examination English / chart composition, English chart composition is enough
Post request body content cannot be retrieved repeatedly
Intel 内部指令 --- AVX和AVX2学习笔记
The differences and relationships among port, targetport, nodeport and containerport in kubenetes
WSL 2 will not be installed yet? It's enough to read this article
Differences between nodes and sharding in ES cluster
Those logs in MySQL
mysql数据库基础
Fastdateformat why thread safe