当前位置:网站首页>深拷貝 事件總線
深拷貝 事件總線
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);
边栏推荐
- mysql数据库基础
- Sub thread get request
- 基于Arduino和ESP8266的连接手机热点实验(成功)
- 【C语言】杨辉三角,自定义三角的行数
- The differences and relationships among port, targetport, nodeport and containerport in kubenetes
- Leetcode122 买卖股票的最佳时机 II
- Leetcode922 sort array by parity II
- 甜心教主:王心凌
- Drools terminates the execution of other rules after executing one rule
- Error in kubeadm join: [error port-10250]: port 10250 is in use [error fileavailable--etc kubernetes PKI
猜你喜欢
Take you ten days to easily finish the finale of go micro services (distributed transactions)
Map and set
基于Arduino和ESP8266的Blink代码运行成功(包含错误分析)
Use sqoop to export ads layer data to MySQL
深拷贝 事件总线
MySQL and PostgreSQL methods to grab slow SQL
Initial JDBC programming
Drools dynamically add, modify, and delete rules
堆(優先級隊列)
初始JDBC 编程
随机推荐
FastDateFormat为什么线程安全
drools动态增加、修改、删除规则
CPU指令集介绍
Simple use of drools decision table
OpenCV中cv2.VideoWriter_fourcc()函数和cv2.VideoWriter()函数的结合使用
Discrimination of the interval of dichotomy question brushing record (Luogu question sheet)
堆(优先级队列)
The programmer and the female nurse went on a blind date and spent 360. He packed leftovers and was stunned when he received wechat at night
Those logs in MySQL
防抖 节流
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
Jenkins user rights management
Record the range of data that MySQL update will lock
5g era, learning audio and video development, a super hot audio and video advanced development and learning classic
Find the factorial of a positive integer within 16, that is, the class of n (0= < n < =16). Enter 1111 to exit.
(C语言)输入一行字符,分别统计出其中英文字母、空格、数字和其它字符的个数。
In development, why do you find someone who is paid more than you but doesn't write any code?
深入理解P-R曲线、ROC与AUC
mysql表的增删改查(进阶)
倍增 LCA(最近公共祖先)