Pārlūkot izejas kodu

对象创建、类型比对、合并、浅拷贝、深拷贝

DESKTOP-MK04A0R\chuck 3 gadi atpakaļ
vecāks
revīzija
e54492cbfb
3 mainītis faili ar 218 papildinājumiem un 1 dzēšanām
  1. 56 0
      07/index.html
  2. 161 0
      07/src/index.js
  3. 1 1
      README.md

+ 56 - 0
07/index.html

@@ -0,0 +1,56 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="UTF-8">
+    <meta http-equiv="X-UA-Compatible" content="IE=edge">
+    <meta name="viewport" content="width=device-width, initial-scale=1.0">
+    <title>Document</title>
+    <script src="./src/index.js"></script>
+</head>
+<body>
+    <script>
+        function Person(name,age){
+            this.name = name
+            this.age = age
+            //return {}
+        }
+        const p = new Person('zhangsan',18)
+        console.log(p)
+        const p2 = newInstance(Person,'lisi',19)
+        console.log(p2)
+
+        //检测
+        console.log(p instanceof Person)
+        console.log(myInstanceOf(p,Person))
+
+        //对象合并 重名不会覆盖 重复的形成数组
+        const obj1 = {
+            a:[{x:2},{y:3}],
+            b:1,
+            c:{d:4}
+        }
+        const obj2 = {
+            b:2,
+            c:6,
+            a:2
+        }
+        console.log(mergeObject(obj1,obj2))
+
+        //浅拷贝1
+        const result = clone1(obj1)
+        obj1.c.d = 2
+        console.log(result)
+
+        //浅拷贝2 
+        const result2 = clone2(obj1)
+        obj1.c.d = 2
+        console.log(result2)
+
+        //深拷贝1 -- JSON.stringify 不能克隆方法、不能循环引用
+        console.log(deepClone1(obj1))
+
+        //深拷贝2 -- 递归
+        console.log(deepClone1(obj2))
+    </script>
+</body>
+</html>

+ 161 - 0
07/src/index.js

@@ -0,0 +1,161 @@
+/**
+ * 模拟构造函数创建对象
+ * @param {*} Fn 
+ * @param  {...any} args 
+ * @returns 
+ */
+function newInstance(Fn,...args){
+    const obj = {}
+    const result = Fn.call(obj,...args)
+    obj.__proto__ = Fn.prototype
+    return result instanceof Object ? result : obj
+}
+/**
+ * 判断
+ * @param {*} obj 
+ * @param {*} Fn 
+ * @returns 
+ */
+function myInstanceOf(obj,Fn){
+    let prototype = Fn.prototype
+    let proto = obj.__proto__
+    while(proto){
+        if(proto === prototype){
+            return true
+        }
+        proto = proto.__proto__
+    }
+    return false
+}
+/**
+ * 合并数组
+ * @param  {...any} objs 
+ * @returns 
+ */
+function mergeObject(...objs){
+    const result = {}
+    objs.forEach(obj =>{
+        //获取所有属性
+        Object.keys(obj).forEach(key=>{
+            //检测result是否存在key
+            if(result.hasOwnProperty(key)){
+                result[key] = [].concat(result[key],obj[key])
+            }else{
+                result[key] = obj[key]
+            }
+        })
+    })
+    return result
+}
+/**
+ * 浅拷贝1
+ * @param {*} target 
+ * @returns 
+ */
+function clone1(target){
+    if(typeof target === 'object' && target !== null){
+        if(Array.isArray(target)){
+            return [...target]
+        }else{
+            return {...target}
+        }
+    }
+    return target
+}
+/**
+ * 浅拷贝2
+ * @param {*} target 
+ * @returns 
+ */
+ function clone2(target){
+    if(typeof target === 'object' && target !== null){
+        //创建容器
+        const result = Array.isArray(target)?[]:{}
+        for(let key in target){
+            //判断当前对象是否包含该属性
+            if(target.hasOwnProperty(key)){
+                result[key] = target[key]
+            }
+        }
+        return result
+    }
+    return target
+}
+
+/**
+ * 深拷贝1 缺点:不能克隆方法、不能循环引用
+ * @param {*} target 
+ * @returns 
+ */
+function deepClone1(target){
+    return JSON.parse(JSON.stringify(target))
+}
+/**
+ * 深拷贝2 未能解决循环引用
+ * @param {*} target 
+ * @returns 
+ */
+function deepClone2(target){
+    if(typeof target === 'object' && target !== null){
+        const result = Array.isArray(target)?[]:{}
+        for(let key in target){
+            if(target.hasOwnProperty(key)){   //此处可枚举,防止原型属性被拷贝
+                result[key] = deepClone2(target[key])
+            }
+        }
+        return result
+    }else{
+        return target
+    }
+}
+
+/**
+ * 深拷贝3 解决循环引用
+ * @param {*} target 
+ * @param {*} map 
+ * @returns 
+ */
+ function deepClone2(target,map = new Map()){
+    if(typeof target === 'object' && target !== null){
+        let cache = map.get(target)
+        if(cache) return cache
+        const result = Array.isArray(target)?[]:{}
+        map.set(target,result)
+        for(let key in target){
+            if(target.hasOwnProperty(key)){   //此处可枚举,防止原型属性被拷贝
+                result[key] = deepClone3(target[key],map)
+            }
+        }
+        return result
+    }else{
+        return target
+    }
+}
+
+/**
+ * 深拷贝4 性能优化 for in效率较低,使用foreach和object.keys
+ * @param {*} target 
+ * @param {*} map 
+ * @returns 
+ */
+ function deepClone2(target,map = new Map()){
+    if(typeof target === 'object' && target !== null){
+        let cache = map.get(target)
+        if(cache) return cache
+        let isArray = Array.isArray(target)
+        const result = isArray?[]:{}
+        map.set(target,result)
+        if(isArray){
+            target.forEach((item,index)=>{
+                result[index] = deepClone4(item,map)
+            })
+        }else{
+            Object.keys(result).forEach(key =>{
+                result[key] = deepClone4(target[key],map)
+            })
+        }
+        return result
+    }else{
+        return target
+    }
+}

+ 1 - 1
README.md

@@ -5,7 +5,7 @@
 * 04 函数节流与防抖
 * 05 es6数组函数封装 map、reduce、filter、find、findIndex、every、some
 * 06 数组的去重、合并、slice、扁平化、分块、差集、删除、获取
-
+* 07 对象创建、类型比对、合并、浅拷贝、深拷贝
 ## 运行
 npm i
 npm start