Deep clone and prototype chain

Deep clone

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
<script>
    // 乞丐版深拷贝
    // 缺点很明显:
    // 1.当遇到RegExp,Error这些对象的时候,将只得到空对象
    // 2.当遇到undefined,函数这些的时候会被忽略
    // 3.当遇到NaN、Infinity和-Infinity这些的时候,会变成null
    let User = {
     
     
        name: "peter",
        age: 18,
        details: {
     
     
            color: "orange",
            size: 12
        },
        data: [new Date(1536627600000), new Date(1540047600000)],
        func() {
     
     
            console.log(123)
        }
    }

    let User2 = JSON.parse(JSON.stringify(User));

    User.details.color = 'yellow';
    console.log(User);
    console.log(User2);
</script>
</body>
</html>

Ordinary deep clone

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>
<body>
<script>
    // 继承函数递归赋值
    let user = {
     
     
        name: "peter",
        age: 18,
        details: {
     
     
            color: "orange",
            size: 12
        },
        data: [new Date(1536627600000), new Date(1540047600000)],
        func() {
     
     
            console.log(123)
        }
    }

    function deepClone(obj) {
     
     
        // 排除null情况
        if (obj === null) return null;
        // 排除不是object对象情况
        if (typeof obj !== 'object') return obj;
        // 排除正则
        if (obj instanceof RegExp) new RegExp(obj);
        // 排除Date对象
        if (obj instanceof Date) new Date(obj);

        // 创建新对象,使用原型继承的方式
        let newObj = new obj.constructor

        // 使用for in循环将之前的对象赋值给新对象
        for (let val in obj) {
     
     
            if(obj.hasOwnProperty(val)){
     
     
                // 递归调用原对象,使其可以深克隆
                newObj[val] = deepClone(obj[val]);
            }
        }
        return newObj;
    }

    let user2 = deepClone(user);
    user2.details.color = 'yellow';
    console.log(user, user2);
    console.log(user === user2);
</script>
</body>
</html>

How to determine whether a variable is an array

console.log(arr instanceof Array);

How to understand the prototype nature of class?

  • constructor

  • Attributes

  • method

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <script>
        class Student {
           
           
            constructor(name, number) {
           
           
                this.name = name;
                this.number = number;
            }
    
            sayHi(){
           
           
                console.log(`姓名:${
             
             this.name}\n学号:${
             
             this.number}`)
            }
        }
        
        let lisi = new Student('李四', 28);
        lisi.sayHi()
        console.log(lisi.name)
        console.log(lisi.number)
    </script>
    </body>
    </html>
    
  • extends

  • super

    <!doctype html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <meta name="viewport"
              content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
        <title>Document</title>
    </head>
    <body>
    <script>
        class Animal {
           
           
            constructor(name, age) {
           
           
                this.name = name;
                this.age = age;
            }
    
            sayHi() {
           
           
                console.log(`姓名:${
             
             this.name}\n年龄:${
             
             this.age}`)
            }
        }
    
        class Cat extends Animal {
           
           
            constructor(name, age, type) {
           
           
                // super关键字用于访问和调用一个对象的父对象上的函数
                super(name, age);
                this.type = type;
            }
            introduces() {
           
           
                console.log(`我叫${
             
             this.name},今年${
             
             this.age}岁了,属于${
             
             this.type}`)
            }
        }
    
        let tom = new Cat('tom', 8, '猫科动物');
        tom.introduces()
    </script>
    </body>
    </html>
    
  • prototype

    // class实际上是函数,可见是语法糖
    typeof Animal // 'function'
    typeof Cat // 'function'
    
    // 隐式原型和显示原型
    console.log(tom.__proto__ === Student.prototype)
    

  • Prototype relationship

    1. Each class has a display prototypeprototype
    2. Each instance has an implicit prototype__proto__
    3. The implicit prototype of the instance === the displayed prototype of the class
  • Prototype-based execution rules

    1. When getting object properties or methods
    2. First look for this attribute and method on itself
    3. Without this attribute and method, it will automatically go __proto__to look for, if __proto__on but could not find, NULL is returned
  • Prototype chain

    // 子类的显示原型上有一个隐式原型,它与父类的显示原型相等
    console.log( Cat.prototype.__proto__ === Animal.prototype )
    

Insert picture description here

Guess you like

Origin blog.csdn.net/qq_39208971/article/details/109400739