继承和深拷贝封装

本文详细介绍了JavaScript中ES5的寄生组合式继承、ES6类的继承以及深拷贝函数的实现,包括属性和方法的继承机制,以及如何在构造函数和原型上操作,以及手动复制对象的深拷贝技术。
摘要由CSDN通过智能技术生成

继承和深拷贝封装

1.es5寄生组合式继承

2.es6类的继承

3.深拷贝函数封装

01-es5寄生组合式继承

# 属性的继承
`方法`: 在子构造函数内部通过call方法调用父构造函数:
`代码`function Son() {
    Father.call(this, 属性)
}
`原理`:子构造函数内部的this会指向s这个实例对象,通过在子构造函数内用call方法调用父构造函数,将父构造函数内部的this指向强制改变成了s这个实力对象,原本挂载到父构造函数身上的属性,自然就挂载到了s实例对象上了

# 方法的继承
`方法`:强制将子构造函数的原型对象的隐式原型指向父构造函数的原型对象
`代码`Son.prototype = Object.create(Father.prototype)
`原理`:强制将子构造函数的原型对象的隐式原型指向父构造函数的原型对象,通过原型链关系图,子构造函数的实例对象就可以使用父构造函数原型对象上的方法
`Object.create(obj)`: 拷贝一个新对象,新对象的隐式原型会指向源对象

# 手动将子构造函数的原型对象的构造器指回子构造函数本身
`代码`Son.prototype.constructor = Son

完整代码


function Father(chick, duck, sheep) {
    this.chick = chick
    this.duck = duck
    this.sheep = sheep
}

Father.prototype.farm = function () {
    console.log('种田');
}

function Son(chick, duck, sheep, pig) {
    // 注意:先继承再自有
    // 1. 属性的继承
    Father.call(this, chick, duck, sheep)
    // son自己的属性
    this.pig = pig
}

// 2. 方法的继承:
// 注意:Son.prototype.__proto__ === Father.prototype: 子构造函数的原型对象的隐式原型指向了父构造函数的原型对象


Son.prototype = Object.create(Father.prototype)

Son.prototype.code = function () {
    console.log('敲代码');
}

// 3. 手动将子构造函数的原型对象的构造器指回子构造函数本身
Son.prototype.constructor = Son

let s = new Son('鸡', '鸭', '羊', '猪')
s.farm();
s.code();
console.log(s);


// 构造器:指回构造函数本身
console.log(Son.prototype.constructor);

02-es6类的继承

`语法`class 子类 extends 父类 {
    constructor(属性) {
        // 属性的继承
        super(父类的属性)
        this.xxx = xxxx
    }
}

`注意`1. 当使用了extends关键词的时候,就直接把父类的方法继承过来了
    2. 当子类有自己的属性时,必须先继承,再自有
    3. 静态方法属于父类自己独有,不可以被实例对象使用,也不可以被继承
    
`完整代码`class Father {
     // 构造器函数:绑定对象的属性
     constructor(chick, duck, sheep) {
         this.chick = chick
         this.duck = duck
         this.sheep = sheep
     }

     // 原型方法: 挂载到prototype原型对象上的方法
     farm() {
         console.log('种田');
     }

     // 静态方法:构造函数独有的方法,不可以被实例对象使用,也不可以被继承
     static dmj() {
         console.log('打麻将');
     }
 }

// 类的继承:extends: 子类 extends 父类 {}
class Son extends Father {
    constructor(chick, duck, sheep, pig) {
        // 注意:先继承再自有
        // 属性的继承:super关键字实现: super(需要继承的属性,...)
        super(chick, duck, sheep)
        // pig: Son自有的属性
        this.pig = pig
    }

    // 子类自己的原型方法
    code() {
        console.log('敲代码');
    }
}


let s = new Son('鸡', '鸭', '羊', '猪')

console.log(s);
// 1. 当使用了extends关键词的时候,就已经把父类的原型方法继承过来的
s.farm()
s.code()
s.dmj()

03-深拷贝函数的封装【笔试】

# 手写深拷贝函数

 let obj = {
            uname: '小妲己',
            age: 18,
            team: ['坤坤', '波波', '迪迪', '凡凡'],
            company: {
                add1: '科技一路',
                add2: '科技六路',
                add3: ['立人科技', 'B座']
            },
            un: undefined,
            nu: null,
            reg: /^[0-9]$/,
            show: function () {
                console.log('秀儿');
            }
        }

        // 思路:遍历需要拷贝的数据类型,分为3种情况:1. 如果是数组或对象,就继续遍历,直到得到基本数据类型;2. 如果是函数,就调用bind方法复制一份即可;3. 如果是基本类型,就直接用等号赋值即可

        // 1. 遍历的既可以是对象,也可以是数组,使用for...in遍历
        // 2. 判断的数据类型包含了所有可能的情况,必须使用Object.prototype.toString.call()


        // 1. 封装判断数据类型的方法
        function getType(data) {
            return Object.prototype.toString.call(data)
        }

        // 2. 封装对数组的判断
        function isArray(data) {
            return getType(data) === '[object Array]'
        }

        // 3. 封装对对象的判断
        function isObj(data) {
            return getType(data) === '[object Object]'
        }

        // 4. 封装对函数的判断
        function isFunction(data) {
            return getType(data) === '[object Function]'
        }


        // 5. 封装深拷贝函数
        function cloneDeep(target) {
            // 5.1 判断拷贝的是对象还是数组
            var newTarget = isArray(target) ? [] : {}
            // 5.2 遍历要拷贝的数据
            for (var key in target) {
                // 如果是数组或对象,就继续遍历,直到得到基本数据类型
                if (isArray(target[key]) || isObj(target[key])) {
                    newTarget[key] = cloneDeep(target[key])
                } else if (isFunction(target[key])) {
                    // 如果是函数,就调用bind方法复制一份即可
                    newTarget[key] = target[key].bind()
                } else {
                    // 如果是基本类型,就直接用等号赋值即可
                    newTarget[key] = target[key]
                }
            }
            return newTarget
        }

        let newObj = cloneDeep(obj)
        console.log(newObj);

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值