zoukankan      html  css  js  c++  java
  • JavaScript里继承的实现

    真正的面向对象语言必须支持继承机制,即一个类能够重用(继承)另一个类的方法和属性,在上一篇文章里介绍了 javascript 里的类实现 ,这里介绍下继承的实现。
    JavaScript里的继承机制并不是明确规定的,而是通过模仿实现的。
    一:对象冒充(object masquerading)
    对象冒充是如何在函数环境中使用this关键字后发展起来的,其原理如下:构造函数使用this关键字给所有的属性和方法赋值(采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可以使用ClassA的构造函数成为ClassB的方法,然后调用它。ClassB就会收到ClassA的构造函数中定义的属性和方法。

    function ClassA(sColor)
    {
        
    this.color = sColor;
        
    this.sayColor = function()
        
    {
            alert(
    this.color);
        }
    ;
    }

    function ClassB(sColor)
    {
        
    this.newMethord= ClassA;
        
    this.newMethod(sColor);
        
    delete this.newMethod;
    }
    上面的代码中ClassA赋予了方法newMethod(函数只是指向它的指针)。然后调用了该方法,传递给它的是ClassB的构造函数的参数sColor。最后的代码删除了对ClassA的引用,这样以后就不能再调用它了,所有的新属性和新方法都必须在删除了新方法的代码行后定义,否在会覆盖超类的相关属性和方法:
    function ClassB(sColor,sName)
    {
        
    this.newMethor = ClassA;
        
    this.newMethor(sColor);
        
    delete this.newMethor;
        
        
    this.name = sName;
        
    this.sayName = function()
        
    {
            alert(
    this.name);
        }
    ;
    }
    二:call()方法
    call()方法是与经典的对象冒充方法最相似的方法,它的第一个参数用作this的对象,其它参数都直接传递给函数自身,如:
    function sayColor(sPrefix,sSuffix)
    {
        alert(sPrefix 
    + this.color + sSuffix);
    }

    var obj = new object();
    obj.color 
    = "red";
    sayColor.call(obj,
    "The color is ",", a very nice color indeed.");
    //outputs "The color is red, a very nice color indeed."
      在上面的例子里,函数sayColor()在对象外定义,即使它不属于任何对象,也可以引用关键字this,对象obj的color属性等于"red",调用call()方法时对一个参数是obj,说明应赋予sayColor()函数中的this关键字是obj,要与继承机制的对象冒充方法一起使用该方法,只需将前三行的赋值,调用和删除代码替换:
    function ClassB(sColor,sName)
    {
    //    this.newMethor = ClassA;
    //
        this.newMethor(sColor);
    //
        delete this.newMethor;
        ClassA.call(this,sColor);
        
        
    this.name = sName;
        
    this.sayName = function()
        
    {
            alert(
    this.name);
        }
    ;
    }

    三:apply()方法
    apply()方法有二个参数,用作this的对象和要传递给函数的参数数组,列如:
    function sayColor(sPrefix,sSuffix)
    {
        alert(sPrefix 
    + this.color + sSuffix);
    }

    var obj = new object();
    obj.color 
    = "red";
    sayColor.apply(obj,
    new Array("The color is ",", a very nice color indeed."));
    //outputs "The color is red, a very nice color indeed."
    四:原型链
    prototype对象是个模板,要实例化的对象都以这个模板为基础,prototype对象的任何属性和方法都被传递给那个类的所有实例,原型链用这种功能实现继承机制:
    function ClassA()
    {
    }


    ClassA.prototype.color 
    = "red";
    ClassA.prototype.sayColor 
    = function()
    {
        alert(
    this.color);
    }
    ;

    function ClassB()
    {
    }

    ClassB.prototype 
    = new ClassA();
    ClassB.prototype = new ClassA(); 这句把ClassB的prototype属性设置为ClassA的实例,与对象冒充相似,子类的所有属性和方法都必须出现在prototype属性被赋值后,因为在它之前所有的方法都会被删除,因为prototype属性被替换成了新的对象,添加了新的原始对象将被销毁,所以,为ClassB类添加name属性和sayName()方法的代码如下:
    function ClassB()
    {
    }


    ClassB.prototype 
    = new ClassA();

    ClassB.prototype.name 
    = "";
    ClassB.prototype.sayName 
    = function()
    {
        alert(
    this.name);
    }
    ;
    五:混合方式
    这种方式使用构造函数定义类,并未使用任何原型。重写前面的例子,代码如下:
    function ClassA(sColor)
    {
        
    this.color = sColor;
    }

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

    ClassB.prototype 
    = new ClassA();
    ClassB.prototype.sayName 
    = function()
    {
        alert(
    this.name);
    }
     
     
  • 相关阅读:
    TCP/IP的确认号,序列号和超时重传的学习笔记
    Linux进程的虚拟内存
    Linux内存:物理内存管理概述
    Linux进程: task_struct结构体成员
    Linux进程:管理和调度
    Golang基础(8):go interface接口
    技术管理:团队建设
    从分布式一致性谈到CAP理论、BASE理论
    技术管理:项目管理概要
    [译]深入 NGINX: 为性能和扩展所做之设计
  • 原文地址:https://www.cnblogs.com/hdjjun/p/1223749.html
Copyright © 2011-2022 走看看