js继承的实现

js继承问题的实现。

1)call的用法和理解:

调用对象的一个方法,以另一个对象代替当前对象。

例子1:

obj1.method1.call(obj2,argument1,argument2);//call的作用就是把obj1的方法method1放到对象obj2的身上实现,后面作为参数传进去。

            function add(a,b){
                document.writeln(a+b);
            }
            function sub(a,b){
                document.writeln(a-b);
            }
            
            add.call(sub,3,1);//输出4,用的是add方法,放在sub里实现。

例子2:

            function class1(name){
                this.name = name;
                this.showName = function(){
                    document.writeln(this.name);
                }
            }
            
            function class2(name){
                this.name = name;
            }
            
            var c1 = new class1('c1');
            var c2 = new class2('c2');
            
            c1.showName.call(c2);//输出c2

解释:把c1的showName方法放到c2上来实现,c2本来是没有showName方法的,这样c2调用了showName方法输出c2。

例子3(用call来实现继承):

            function class1(){
                this.showTxt = function(txt){
                    document.writeln(txt);
                }
            }
            
            function class2(){
                class1.call(this);
            }
            
            var c2 = new class2();
            c2.showTxt('c2');

解释:这样class2就继承class1了,class1.call(this)的意思是:把class1的方法在this对象里使用,这样class2就可以使用class1的所有方法了。

例子4(实现多重继承):

            function class1(){
                this.showAdd = function(a,b){
                    document.writeln(a+b);
                }
            }
            
            function class2(){
                this.showSub = function(a,b){
                    document.writeln(a-b);
                }
            }
            
            function class3(){
                class1.call(this);
                class2.call(this);
            }
            
            var c3 = new class3();
            c3.showAdd(10,9);
            c3.showSub(10,9);

2)js常用的两种继承。

1>原型链继承(对象间的继承):

            function Parent(){
                this.name = 'mike';
            }
            
            function Child(){
                this.age = 12;
            }
            Child.prototype = new Parent();//Child继承了Parent,通过原型,形成链条
            
            var c1 = new Child();
            document.writeln(c1.age);
            document.writeln(c1.name);//c1继承了Parent的属性
            
            function Brother(){
                this.weight = 60;
            }
            
            Brother.prototype = new Child();//Brother继承了Child,通过原型,形成链条
            
            var brother = new Brother();
            document.writeln(brother.name);
            document.writeln(brother.age);

解释: 以上原型链继承还缺少一环,那就是Object,所有的构造函数都继承Object。而继承Object是自动完成的,并不需要我们自己手动继承。

PS:(1)确定原型和实例的关系:

可以通过两种方式来确定原型和实例之间的关系。操作符instanceof和isPrototypeof方法:

            document.writeln(brother instanceof Object);
            document.writeln(c1 instanceof Brother); //false
            document.writeln(brother instanceof Child);
            document.writeln(brother instanceof Parent);

        (2)使用原型继承有两个问题:<1> 重写原型会中断关系<2>子类型还无法给超类型传递参数

2>类式继承(借用构造函数):

            function Parent(age){
                this.name = ['mike','joe','smith'];
                this.age = age;
            }
            
            function Child(age){
                Parent.call(this,age);
            }
            
            
            var c1 = new Child(21);
            document.writeln(c1.age);
            document.writeln(c1.name);
            c1.name.push('bill');
            document.writeln(c1.name);

解释: 借用构造函数虽然解决了刚才两种问题,但没有原型,则复用无从谈起,所以我们需要原型链+借用构造函数的模式,这种模式称为组合继承。

3)组合继承(原型链+类式继承)

例子:

            function Parent(age){
                this.name = ['mike','jack','smith'];
                this.age = age;
            }
            Parent.prototype.run = function(){
                return this.name + 'are both' + this.age;
            };
            function Child(age){
                Parent.call(this,age);//给超类型传参数,借用构造函数
            }
            Child.prototype = new Parent();//原型链继承
            var c1 = new Child(21);//写成Parent(21)也可以
            document.writeln(c1.run());

解释: 组合式继承是比较常用的一种继承方法,其背后的思路是 使用原型链实现对原型属性和方法的继承,而通过借用构造函数来实现对实例属性的继承。

4)原型式继承

解释: 这种继承借助原型并基于已有的对象创建新对象,同时还不用创建自定义类型的方式称为原型式继承

例子:

            function obj(o){
                function F(){}
                F.prototype = o;
                return new F();
            }
            var box = {
                name:'tiger',
                arr:['brother','sister','father']
            };
            var b1 = obj(box);
            document.writeln(b1.name+"<br>");
            
            b1.name = 'mike';
            document.writeln(b1.name+"<br>");
            
            document.writeln(b1.arr+"<br>");
            b1.arr.push('parents');
            document.writeln(box.arr+"<br>");//b1插入后,父类的属性同样改变
            document.writeln(b1.arr+"<br>");
            
            var b2 = obj(box);
            document.writeln(b2.name+"<br>");
            document.writeln(b2.arr);

解释: 原型式继承首先在obj函数内部创建一个临时性的构造函数 ,然后将传入的对象作为这个构造函数的原型,最后返回这个临时类型的一个新实例。

5)寄生式继承

解释: 这种继承方式是把原型式+工厂模式结合起来,目的是为了封装创建的过程。

            function obj(o){
                function F(){}
                F.prototype = o;
                return new F();
            }
            function create(o){
                var f = obj(o);
                f.run = function(){
                    return this.arr;
                };
                return f;
            }
            var box = {
                name:'tiger',
                arr:['brother','sister','father']
            };
            
            var f1 = create(box);
            document.writeln(f1.name+'<br>');
            document.writeln(f1.arr+'<br>');
            document.writeln(f1.run());

6)寄生组合式继承

解释: 但组合继承的超类型在使用过程中会被调用两次;一次是创建子类型的时候,另一次是在子类型构造函数的内部 ,寄生组合继承,解决了两次调用的问题。

例子:

            function obj(o){
                function F(){}
                F.prototype = o;
                return new F();
            }
            function inheritPrototype(child,parent){
                var prototype = obj(parent.prototype);//创建对象
                prototype.constructor = child;//增强对象
                child.prototype = prototype;//自定对象
            }
            function parent(name){
                this.name = name;
                this.color = ['red','yellow','green'];
            }
            parent.prototype.sayName = function(){
                document.writeln(this.name);
            }
            
            function child(age){
                parent.call(this,name);
                this.age = age;
            }
            inheritPrototype(child,parent);
            child.prototype.sayAge = function(){
                document.writeln(this.age);
            }
            var p1 = new parent('p1');
            var c1 = new child('12');
            document.writeln(p1.name+'<br>');
            document.writeln(p1.age+'<br>');
            document.writeln(p1.color+'<br>');
            document.writeln(c1.name+'<br>');
            document.writeln(c1.age+'<br>');
            document.writeln(c1.sayName()+'<br>');

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/u/3347640/blog/858881

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值