js高阶——面向对象.ES5对象继承

        3、组合继承(原型链继承 + 构造函数继承)

           好处

            1、初始属性被继承到了自身,所以单个实例对象之间初始属性是独立的,互相没有联系。

            2、结合原型链继承,多个实例之间也有共同的父对象(父的实例对象),如果未来需要

               同时为多个实例附加新的属性或方法时,可以找到父对象来附加。

 

        function 钱多多() {
            this.money = 'max';
        }

        function 穷光蛋() {
            钱多多.call(this);
            this.happiness = 'max';
        }

        穷光蛋.prototype = new 钱多多();
        穷光蛋.prototype.constructor = 穷光蛋;

        const 张三 = new 穷光蛋();
        const 李四 = new 穷光蛋();

        李四.happiness = 'min';
        李四.money = 'null';//有继承关系,但是存在多态关系,所以改变李四对象的值,张三不影响。

        4、原型继承

Object.create 这个方法可以实现普通对象的继承,不仅仅能继承属性,统一也可以继承abc方法。

缺点,多个实例继承的是同一个对象,任何一个实例改变了父对象,其他实例的父对象也会跟着变。

 

const 马 = { money: 10000000000000 };

const 腾 = {
    腾腾: { money: 10000 }
};

马.__proto__.abc = function () {
    return 123
}

const 张三1 = Object.create(马);
const 李四1 = Object.create(马);

        console.log(
            张三1 == 李四1//false 
        )
        console.log(
            张三1.腾腾.money
        )
        console.log(
            李四1.腾腾.money
        )
//Object.create 这个方法可以实现普通对象的继承,不仅仅能继承属性,统一也可以继承abc方法。
//缺点,多个实例继承的是同一个对象,任何一个实例改变了父对象,其他实例的父对象也会跟着变。

        5、寄生式继承(工厂模式实现原型继承)

            //工厂模式

            //生成一个新对象,让这个新对象继承参数对象,做处理,最后返回。  

            优缺点与4一致,只是写法上有变化,由函数返回新继承来的对象。

            为什么要有寄生式继承,因为工厂模式能够很好的将继承后的子对象做二次处理,且封装,利于阅读。

 

        const 马腾 = { money: 10000000000000 };

        马腾.__proto__.abc = function () {
            return 123
        }

        //工厂模式
        //生成一个新对象,让这个新对象继承参数对象,做处理,最后返回。 
        function clone(obj) {
            const child = Object.create(obj);
            child.a = 123;
            child.abc = 1;//此条会覆盖父属性abc的值。
            return child;
        }

        const 张三2 = clone(马腾);
        const 李四2 = clone(马腾);

        console.log(
            张三2.__proto__
        )
        console.log(
            张三2.a
        )
        console.log(
            张三2.abc
        )




        const 父 = {
            长相: { 曾经: '帅' }
        }
        父.__proto__.abc = function () {
            return 123
        }

        //工厂模式
        //生成一个新对象,让这个新对象继承参数对象,做处理,最后返回。
        function clone(父) {
            const clone = Object.create(父);
            clone.abc = 12;
            return clone;
        }

        const 张三 = clone(父);
        const 李四 = clone(父);

        李四.长相.曾经 = '丑'

        console.log(张三.abc)

        6、寄生组合式继承

            结合第四种中提及的继承方式,解决普通对象的继承问题的 Object.create 方法,我们在前面这几种

            继承方式的优缺点基础上进行改造,得出了寄生组合式的继承方式,在es5中这也是所有继承方式里面相

            对最优的继承方式。

            在js中任何值都是对象(万事万物皆对象)。

            所有的对象都有一个共同的祖先(对象原型),对象原型没有祖先(null)

            对象的属性或方法,有私有,如果没有,会顺着原型链一直向上找,直到原型对象。

            一般创建的都是第三代

 

        function 钱多多1() {
            this.money = 1000;//this执行器的执行上下文
        }
        function 穷光蛋1() {
            钱多多1.call(this);
            this.happiness = true;
        }

        clone(钱多多1, 穷光蛋1)
        function clone(father, child) {
            child.prototype = Object.create(钱多多1.prototype);
            child.prototype.constructor = child;
            child.prototype.abc = 123;
            child.a = 123;//undefined  没有创建他的属性,所以只能在外层用子对象.属性名的形式添加属性,工厂模式使用const创建了对象
            return child;

        }

        const 张三3 = new 穷光蛋1();//new后生成的函数对象,在执行函数后的this指向未来生成的对象,不管写不写都会有this指向
        const 李四3 = new 穷光蛋1();
        穷光蛋1.prototype.abc = 456;//如果外边改变创建对象的值,则子实例对象的值都会发生改变。
        李四3.__proto__.abc = 789//可以要 也可以不要原型对象属性。

        console.log(
            张三3.__proto__.constructor == 李四3.constructor
        )
        console.log(
            张三3.__proto__//加f才是函数,实际打出来的是对象。
        )
        console.log(
            张三3
        )
        console.log(
            李四3
        )
        console.log(
            李四3.__proto__ == 穷光蛋1.prototype





        function 父() {
            this.长相 = { 曾经: '帅' }
        }

        父.prototype.abc = function () {
            return 123
        }

        function 子() {
            父.call(this);
        }

        clone(父, 子);
        function clone(父, 子) {
            //因为没有父类的实例对象,所以创造了一个全新对象(没有必要创建父类的实例对象)
            子.prototype = Object.create(父.prototype);
            子.prototype.constructor = 子;
            子.a = 1;//undefined  没有创建他的属性,所以只能在外层用子对象.属性名的形式添加属性,工厂模式使用const创建了对象。
            子.prototype.abc = 456
            return 子;
        }

        const 张三4 = new 子();
        const 李四4 = new 子();

        李四4.长相.曾经 = '丑'//不能通过这种方式修改父对象属性,只能修改子对象的属性
        张三4.__proto__.abc = '丑'//但是可以通过访问父对象,给对象添加属性。


        console.log(张三4.长相.曾经)
        console.log(李四4.长相.曾经)
        console.log(张三4.abc)
        console.log(李四4.abc)
        console.log(李四4.a)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值