码迷,mamicode.com
首页 > 移动开发 > 详细

js继承之call,apply和prototype随谈

时间:2015-08-13 11:39:01      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

在js中,call,apply和prototype都可以实现对象的继承,下面我们看一个例子:

  function FatherObj1() {
            this.sayhello = "I am join";
            this.show = function () {
                alert("I am FatherObj1");
            };
            this.getall = function () {

                if (arguments)
                    alert("GetAll:" + arguments[0]);
            }

        }
        function FatherObj2() {
            this.sayhi = "I am Tom";
            this.show = function () {
                alert("I am FatherObj2");
            };

        }
        function SonObj() {
            this.sayby = "ByeBye";
            this.show = function () {
                alert("I am SonObj");
            };
          
        }

 

 

1.call&apply继承

我们先说一下 call和apply 的继承方式,

对于call和apply 在实现继承方面只是传参方式有区别,其他基本相同。

SonObj来继承FatherObj1:

function SonObj() {
            this.sayby = "ByeBye";
            this.show = function () {
                alert("I am SonObj");
            };
            FatherObj1.call(this);  //继承方式1
           // FatherObj1.apply(this);//继承方式2

        }

这里的 FatherObj1.call(this); 可以理解为把FatherObj1这个对象里的属性和方法委托给this也就是Sonobj,或者遗传给Sonobj,这种方式与C#,Java的继承不同的是:js可以继承多个父类,而C#,java只能继承一个,

那么问题来了,js继承多个父类,而多个父类如果有同名方法或者同名属性,会发生什么事情?

  function SonObj() {
            this.sayby = "ByeBye";
            this.show = function () {
                alert("I am SonObj");
            };
            FatherObj1.call(this);  //继承方式1
            FatherObj2.call(this);

        }

上面代码我让SonObj同时继承FatherObj1和FatherObj2,大家可以看到,在子类和父类对象里都存在同名方法show,

 var son = new SonObj();
   son.show();

运行之后的结果是:I am FatherObj2,这个结果说明 FatherObj2的show方法把SonObj的同名方法给重写了,下面我调整一下SonObj里面的方法顺序,

 function SonObj() {
            this.sayby = "ByeBye";
           
            FatherObj1.call(this);  //继承方式1
            FatherObj2.call(this);
            this.show = function () {
                alert("I am SonObj");
            };

        }

输出结果:I am SonObj,可见js对同名方法的处理是,执行过程中,后者替代前者,不受子父类的约束,

如果我只想继承FatherObj1的getall方法,不想继承整个类怎么做呢?我们可以这样:

  function SonObj() {
            this.sayby = "ByeBye";
           
            this.show = function () {
                alert("I am SonObj");
            };
        }
        var son = new SonObj();
        var fa = new FatherObj1();
        fa.getall.call(son, 1, 2);  
        fa.getall.apply(son, [1, 2]);

从call和apply 的调用上看,细心的同学应该发现了其中的不同,call的参数是 call(obj,arg1,arg2),而apply的参数是一个对象加一个数组,apply(obj,[arg1,arg2])

我现在给FatherObj2加一个原型方法:

  FatherObj2.prototype.StaticForYou = function () {
            alert("FatherObj2_StaticForYou");

        };

现在我用SonObj去继承这个方法的话,可以这样写:

 FatherObj2.prototype.StaticForYou.call(SonObj.prototype);

或者:

 FatherObj2.prototype.StaticForYou.call(SonObj);

同样,用apply也可以实现,只是很相同,就不写了。

 

2 Prototype的继承:

  

  SonObj.prototype = new FatherObj1();
        var son = new SonObj();

这样,son就有了fatherobj1的所有方法,

同样,我们用son来调用show方法

  son.show();

输出结果是:I am SonObj,而不是父类的方法返回结果,是的,prototype的继承其实就是复制父类的方法和属性,如果自己有同名方法或属性,就不去复制,而保留本身的属性或方法。

那如果我想要调用父类的同名方法怎么做呢?可以把上面代码改成

        var father = new FatherObj1();
        father.show.call(son);

这样相当于又回到了call和apply的继承问题。

现在我们想,既然用call和apply 可以继承多个父类,那我们同理用prototype来试试:

 SonObj.prototype = new FatherObj1();
 SonObj.prototype = new FatherObj2();

这样sonobj会不会继承这两个父类的属性和方法呢?

结果我们发现,已经调用不到FatherObj1的方法了,只能调用到FatherObj2的方法和属性。下面的父类把上面的父类替换掉了。

 SonObj.prototype.StaticForYou = function () {
            alert("Static_Come");
        }
        son.StaticForYou();

输出结果:Static_Come,如果想输出父类的原型方法呢?推一下就出来啦

 FatherObj2.prototype.StaticForYou.call(SonObj);

 

js继承之call,apply和prototype随谈

标签:

原文地址:http://www.cnblogs.com/qiumohanyu/p/4726631.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!