JavaScript 构造函数的继承

对象间的“继承”五种方法:

一、构造函数绑定

    最简单的方法,使用call或apply方法,将父对象的构造函数绑定在子对象上,即在子对象构造函数中加一行:

     范例:

        function Animal() {

            this.species = "动物";

        }

        function Cat(_name, _color) {

            Animal.apply(this, arguments);

            this.name = _name;

            this.color = _color;

        }

        var cat = new Cat("Andy", "White");

        console.log(cat.species); // 动物


二、prototype模式

    使得Cat的prototype对象,指向一个Animal实例,那么所有Cat的实例,就能继承Animal

    范例:

        Cat.prototype = new Animal();

        Cat.prototype.constructor = Cat;

        var cat = new Cat("Andy", "Black");

         console.log(cat.species);

     说明:

        代码第一行(Cat.prototype = new Animal()),将Cat的prototype对象指向一个Animal实例; 它相当于完全删除了原prototype对象的引用值,然后赋予一个新值

        代码第二行(Cat.prototype.constructor = Cat):任何一个prototype对象都有一个constructor属性,指向它的构造函数。如果没有第一行代码(Cat.prototype = new Animal()),Cat.prototype.constructor 是指向Cat的;加入这一行后,Cat.prototype.constructor指向Animal;

        更重要的是,每一个对象实例也有一个constructor属性,默认指向prototype对象的constructor属性

            altert(cat.constructor == Cat.prototype.constructor) // true

三、直接继承prototype

    对prototype模式的改进;由于Animal对象中,不变的属性都直接写入Animal.prototype对象中,所以,可以让Cat()调岗Animal(),直接继承Animal.prototype对象

    范例:

        function Animal() {};

        Animal.prototype.species = "动物";

        //将Cat的prototype对象,指向Animal的prototype对象,就完成继承工作

        Cat.prototype = Animal.prototype;

        Cat.prototype.constructor = Cat; //修改了对象的prototype引用,prototype对象的constructor属性也必须修正

    缺点:

        Cat.prototype和Animal.prototype都指向了同一个对象,那么任何对Cat.prototype的修改,都会反映到Animal.prototype

        代码:Cat.prototype.constructor = Cat,这一句实际上把Animal.prototype对象的constructor属性也改掉了

            console.log(Animal.prototype.constructor); // Cat

四、利用空对象作为中介

    范例:

        var F= function() {};

        F.prototype = Animal.prototype;

        Cat.prototype = new F();

        Cat.prototype.constructor = Cat;

    解释:

        F 是空对象,所以 几乎不占内存;此时,修改Cat的prototype对象,不会影响到Animal的prototype对象

        console.log(Animal.prototype.constructor); // Animal

      再次将上述进行封装:

            function extend(childObj, parentObj) {

                var F = function() {};

                F.prototype = parentObj.prototype;

                childObj.prototype = new F();

                childObj.prototype.constructor = childObj;

                childObj.uber = parentObj.prototype;

            }                

        注:extend()方法,就是YUI库如何实现继承的方法

    使用:

        extend(Cat, Animal);

        var cat = new Cat("Andy", "Black");

        console.log(cat.species); //动物

    另外,函数体最后一行说明(childObj.uber = parentObj.prototype), 意思是为子对象设置一个uber属性,此属性直接指向父对象的prototype对象(uber, 德语词,意思是“向上”、“上一层”),放在此处,只是为了实现继承的完备性,纯属备用性质

五、拷贝继承

    介绍:把父对象的所有属性和方法,拷贝进子对象,从而实现拷贝进程

    实现:

        首先:把Animal所有不变的属性,放到prototype对象上

            function Animal() {};

            Animal.prototype.species = "动物";

        再者,编写新函数,实现属性拷贝目的

            function extend(Child, Parent) {

                var p = Parent.prototype;    

                var c = Child.prototype;

                for (var index in p) {

                    c[index] = p[index];

                }

                c.uber = p;

            }


        使用:

            extend(Cat, Animal);

            var cat = new Cat("Andy", "Black");

            console.log(cat.species); // 动物

                



转载于:https://my.oschina.net/u/1251536/blog/413488

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值