当前位置:网站首页>深拷貝 事件總線
深拷貝 事件總線
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);
边栏推荐
- Drools terminates the execution of other rules after executing one rule
- Docker compose configuration mysql, redis, mongodb
- (C language) 3 small Codes: 1+2+3+ · · +100=? And judge whether a year is a leap year or a normal year? And calculate the circumference and area of the circle?
- CV2 in OpenCV VideoWriter_ Fourcc() function and cv2 Combined use of videowriter() function
- 测试左移和右移
- Day12 control flow if switch while do While guessing numbers game
- Jenkins voucher management
- drools决策表的简单使用
- Post request body content cannot be retrieved repeatedly
- Map and set
猜你喜欢

Addition, deletion, modification and query of MySQL table (Advanced)

Simple understanding of ThreadLocal

Jenkins user rights management

Performance tuning project case

深拷贝 事件总线

MySQL and PostgreSQL methods to grab slow SQL

CDA数据分析——AARRR增长模型的介绍、使用

Why do programmers have the idea that code can run without moving? Is it poisonous? Or what?

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

【工控老马】西门子PLC Siemens PLC TCP协议详解
随机推荐
CDA data analysis -- common knowledge points induction of Excel data processing
Leetcode122 the best time to buy and sell stocks II
5g era, learning audio and video development, a super hot audio and video advanced development and learning classic
Go学习笔记—多线程
drools执行完某个规则后终止别的规则执行
jenkins 凭证管理
Performance tuning project case
Leetcode739 daily temperature
排序---
Jenkins用户权限管理
使用Sqoop把ADS层数据导出到MySQL
Writing method of then part in drools
Drools dynamically add, modify, and delete rules
The second composition template of postgraduate entrance examination English / chart composition, English chart composition is enough
Thesis translation: 2022_ PACDNN: A phase-aware composite deep neural network for speech enhancement
Map和Set
上传文件时,服务器报错:IOFileUploadException: Processing of multipart/form-data request failed. 设备上没有空间
BOM DOM
Leetcode209 长度最小的子数组
寻找二叉树中任意两个数的公共祖先