`
Lewiss
  • 浏览: 19594 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

JavaScript 继承

阅读更多
1. ECMAScript 实现继承的方式不止一种,这是因为 ECMAScript 的继承并不是明确规定的,而是通过模拟实现的。

2. 继承实现的两种方式:对象冒充和原型方式

3. 对象冒充
   
    function ClassA(sColor){
         this.color = sColor;
         this.sayColor = function(){
             alert(this.color);
         }
     }

     function ClassB(sColor){
         this.newMethod = ClassA;
         this.newMethod(sColor);
         delete this.newMethod;
     }

    原理:当调用 this.newMethod(sColor) 时,相当于调用 ClassA 的构造函数。在 ClassA 函数里面,通过 this 来对属性 color 和方法 sayColor 赋值。和 Java 一样,ECMAScript 的 this 保存时调用该方法的对象的引用,所以当在 ClassB 中通过 this.newMethod(sColor) 调用构造函数 ClassA 时,ClassA 中的 this 其实是新创建的 ClassB 的实例。于是新创建的 ClassB 的实例就拥有了 color 属性和 sayColor 方法。
    注意,如果还有其它的属性和方法,必需在 delete this.newMethod 之后执行,否则会覆盖超类中相关的属性和方法。如:
    function ClassB(sColor,sName){
         this.newMethod = ClassA;
         this.newMethod(sColor);
         delete this.newMethod;
     
         this.name = sName;
         this.sayName = function(){
             alert(this.name);
         }
     }

4. 通过 call 方法实现继承
    其实,call 方式实现继承就是对象冒充,它们的实现原理是一样的。它的第一个参数用作函数的 this 对象,其它参数都直接传递给函数自身。示例:

    function ClassB(sColor,sName){
         //this.newMethod = ClassA;
         //this.newMethod(sColor);
         //delete this.newMethod;
         ClassA.call(this,sColor);
     
         this.name = sName;
         this.sayName = function(){
             alert(this.name);
         }
     }

5. 通过 apply 方法实现继承
    原理与 call 方法相同,只不过 apply 只有两个参数,一个是用作 this 的对象,另一个是传递给函数的参数的数组。示例:
   
    function ClassB(sColor,sName){
         //this.newMethod = ClassA;
         //this.newMethod(sColor);
         //delete this.newMethod;
         //ClassA.call(this,sColor);
         ClassA.apply(this,new Array(sColor));
     
         this.name = sName;
         this.sayName = function(){
             alert(this.name);
         }
     }

6. 原型链方式实现继承
   
     function ClassA(){
     }
     ClassA.prototype.color = "red";
     ClassA.sayHello = function(){
          alert(this.color);
     }

     funciton ClassB(){
     }
     ClassB.prototype = new ClassA();

    这就实现了继承。每当 ClassB 被实例化对象时,prototype 里的所有属性都被传递到新的实例中,当然包括 new ClassA();这种做法的弊端是,无法给构造函数传递初始化参数。于是,引出了混合方式的继承实现机制。

7. 混合方式
 
    function ClassA(sColor){
        this.color = sColor;
    }
    ClassA.prototype.sayColor = funciton(){
        alert(this.color);
    }

    function ClassB(sName,sColor){
        ClassA.call(sColor);
        this.name = sName;
    }
    ClassB.prototype = new ClassA();
    ClassB.prototype.sayName = function(){
        alert(this.name);
    }

    定义对象的最好方式是用构造函数定义属性,用原型方式定义方法。这里实现继承机制也是相同的道理。
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics