深克隆与原型原型链

乞版深克隆

<!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>

普通深克隆

<!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>

如何判断一个变量是不是数组

console.log(arr instanceof Array);

class的原型本质,怎么理解?

  • construtor

  • 属性

  • 方法

    <!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>
    
  • 原型

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

  • 原型关系

    1. 每个class都有显示原型prototype
    2. 每个实例都有隐式原型__proto__
    3. 实例的隐式原型===class的显示原型
  • 基于原型的执行规则

    1. 获取对象的属性或方法时
    2. 先在自身上寻找是否有此属性和方法
    3. 若无此属性和方法,那就会自动去__proto__去寻找,如果__proto__上也没有找到,则返回NULL
  • 原型链

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

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值