zoukankan      html  css  js  c++  java
  • javascript设计模式继承(上)

    本章的主题是继承,分为上下两部分来介绍,上主要来介绍call和apply方法,下用来介绍继承的几种实现方式。

      在介绍继承的时候,call和apply是一个绕不过去的话题,也是大家需要深入了解的知识。下面我们来看看call的定义(apply和call基本是一样的,只是参数不同,这里不做介绍了):

    call 方法
    请参阅
    应用于:Function 对象
    要求
    版本 5.5
    调用一个对象的一个方法,以另一个对象替换当前对象。
    call([thisObj[,arg1[, arg2[,   [,.argN]]]]])
    参数
    thisObj
    可选项。将被用作当前对象的对象。
    arg1, arg2, , argN
    可选项。将被传递方法参数序列。
    说明
    call 方法可以用来代替另一个对象调用一个方法。call 方法可将一个函数的对象上下文从初始的上下文改变为由 thisObj 指定的新对象。
    如果没有提供 thisObj 参数,那么 Global 对象被用作 thisObj。

      定义总是让人看不懂,还是直接上例子直接。

    例1:

    复制代码
    function Person(name) {
      this.name = name;
      this.getName = function () {
        return this.name;
      }
    }
    
    function Man(name, age) {
      Person.call(this, arguments[0]);
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var man = new Man('jason', 'man');
    alert(man.getName()); //jason 
    复制代码

    以Person.call(this,argument[0])为例:

    call方法的调用者:一个对象的方法(在js里面方法/函数也是对象),调用者为,Person
    call方法的参数:一个新对象(man),这个对象的作用是“拦截”对象Person,来运行本来属于Person的getName方法;而 argument[0]就是给method传递参数了
    call方法的结果:Person.call(man,argument[0])类似于:man=new Person(argument[0])
    call方法的作用:Person方法得到重用、共享,有new的特效,实现继承。

      那么通过call到底能继承什么内容呢?我通过下面的例子做以介绍。

      上面的例子是在构造函数里面调用了call,那么在构造函数外,代码运行的过程中能否实现继承呢?

    例子2:

    复制代码
    function Person(name) {
      this.name = name;
      this.getName = function () {
        return this.name;
      }
    }
    
    function Man(name, age) {
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var man = new Man('jason', '25');
    Person.call(man, 'jason');
    
    alert(man.getName());//jason
    复制代码

      通过测试,man继承了Person的getName函数。前两次都是用Person去调用call方法,这次我们换成person,看看效果如何。

    例3:

    复制代码
    function Person(name) {
      this.name = name;
      this.getName = function () {
        return this.name;
      }
    }
    
    function Man(name, age) {
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var person = new Person('person');
    var man = new Man('jason', '25');
    
    person.call(man, 'jason');
    alert(man.getName()); //person.call is not a function
    复制代码

      结果报错,原因是其实很简单,call的调用者只能是Function 对象,person是Function的实例,Person才是Function对象。

      那么这次我们用person.getName来调用call,看会是什么样的结果。

    例4:

    复制代码
    function Person(name) {
      this.name = name;
      this.getName = function () {
        return this.name;
      }
    }
    
    function Man(name, age) {
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var person = new Person('person');
    var man = new Man('jason', '25');
    
    person.getName.call(man, 'jason');
    alert(man.getName()); //man.getName is not a function
    复制代码

      在这里肯定会有人疑问了,不是只要做为方法就能调用call吗,那man就应该继承getName啊。前半句话是对的,但是后半句就不一定了。那通过call到底继承了哪些内容呢?

    例5:

    复制代码
    function Person(name) {
      this.name = name;
      this.getName = function () {
        this.address = 'address';  //代码稍加改动,在getName方法中增加了一个变量    
        return this.name;
      }
    }
    
    function Man(name, age) {
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var person = new Person('person');
    var man = new Man('jason', '25');
    
    person.getName.call(man, 'jason');
    
    //在这里我们遍历man,看他到底包含了哪些对象
    for (pro in man) {
      alert(pro + ":" + man[pro]);
    }
    //输入结果:
    //age:25
    //setAge:function (age) {
    //    this.age = age;
    //}
    //address:address
    复制代码

      结果很特别吧,居然多了一个address。结果也就很明显了,调用call,call的被调用者会继承调用者内部的实例对象,而不是调用者本身。

      下面我们在做最后一个测试,看call是否能继承对象的prototype里面的对象。

    例6:

    复制代码
    function Person(name) {
      this.name = name;
    }
    
    Person.prototype.getName = function () {
      return this.name;
    }
    
    function Man(name, age) {
      this.age = age;
      this.setAge = function (age) {
        this.age = age;
      }
    }
    
    var man = new Man('jason', '25');
    Person.call(man, 'jason');
    
    alert(man.getName()); //man.getName is not a function
    复制代码

      结果很显然,通过call不能继承调用者的prototype对象,他只能继承调用者内部的实例对象。

      

      今天的内容就到此了,希望对大家有帮助。

    转自:http://www.cnblogs.com/softlover/archive/2012/07/26/2608522.html

  • 相关阅读:
    [POJ 1050]To the Max
    P1678 烦恼的高考志愿
    P1873 砍树
    P1102 A-B 数对
    P6771 [USACO05MAR]Space Elevator 太空电梯
    P2347 砝码称重
    P1832 A+B Problem(再升级)
    P1679 神奇的四次方数
    P1877 [HAOI2012]音量调节
    P1049 装箱问题
  • 原文地址:https://www.cnblogs.com/jackljf/p/3589359.html
Copyright © 2011-2022 走看看