`

java script 继承的实现

阅读更多
ECMAScript 中实现继承的方式不止一种。这是因为 JavaScript 中的继承机制并不是明确规定的,而是通过模仿实现的。这意味着所有的继承细节并非由解释程序处理。



对象冒充--- 构造函数使用 this 关键字给所有属性和方法赋值(即采用类声明的构造函数方式)。因为构造函数只是一个函数,所以可使 ClassA 的构造函数成为 ClassB 的方法,然后调用它。 ClassB 就会收到 ClassA 的构造函数中定义的属性和方法。

Js代码 
function ClassA(sColor){   
    this.color = sColor;   
    this.sayColor = function (){   
        alert(this.color);   
    }   
}  
  
function ClassB(sColor,sName){   
    this.newMethod = ClassA;    //为ClassA赋予了方法newMethod   
    this.newMethod(sColor);     //调用newMethod   
    delete this.newMethod;      //删除对ClassA的引用   
  
    this.name = sName;   
    this.sayName = function(){   
        alert(this.name);   
    }   
}  
 

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

function ClassB(sColor,sName){
	this.newMethod = ClassA;	//为ClassA赋予了方法newMethod
	this.newMethod(sColor);		//调用newMethod
	delete this.newMethod;		//删除对ClassA的引用

	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
} 

所有的新属性和新方法都必须在删除了新方法的代码行后定义。否则,可能会覆盖超类的相关属性和方法.

可以实现多继承



call() 方法--- 与经典的对象冒充方法相似, 第一个参数用作 this 的对象。其他参数都直接传递给函数自身。

Js代码
function ClassA(sColor){   
    this.color = sColor;   
    this.sayColor = function (){   
        alert(this.color);   
    }   
}   
  
function ClassB(sColor,sName){   
    ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象   
                        //第二个参数sColor对两个类来说都是唯一的参数。   
    this.name = sName;   
    this.sayName = function(){   
        alert(this.name);   
    }   
}  

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

function ClassB(sColor,sName){
	ClassA.call(this,sColor);  //this让ClassA中的关键字this等于新创建的ClassB对象
						//第二个参数sColor对两个类来说都是唯一的参数。
	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
}  

apply() 方法--- 与call()相似,两个参数,用作 this 的对象和要传递给函数的参数的数组。

Js代码 
function ClassA(sColor){   
    this.color = sColor;   
    this.sayColor = function (){   
        alert(this.color);   
    }   
}   
  
function ClassB(sColor,sName){   
    ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象   
    ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。   
  
    this.name = sName;   
    this.sayName = function(){   
        alert(this.name);   
    }   
}  

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

function ClassB(sColor,sName){
	ClassA.apply(this,arguments);//只有超类中的参数顺序与子类中的参数顺序完全一致时才可以传递参数对象
	ClassA.apply(this,new Array(sColor));//如果不是,就必须创建一个单独的数组,按照正确的顺序放置参数。

	this.name = sName;
	this.sayName = function(){
		alert(this.name);
	}
} 

原型链--- 用另一类型的对象重写类的 prototype 属性。

prototype 对象的任何属性和方法都被传递给那个类的所有实例。 子类的所有属性和方法都必须出现在 prototype 属性被赋值后,因为在它之前赋值的所有方法都会被删除。

缺点:使用原型链,就无法使用带参构造函数了

Js代码 
function ClassA(){   
}   
  
ClassA.prototype.name = "nomad";   
ClassA.prototype.sayName = function(){   
    alert(this.name);   
}   
  
function ClassB()   
}   
ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。   
  
ClassB.prototype.age = 23;   
ClassB.prototype.sayAge = function(){   
    alert(this.age);   
}  

function ClassA(){
}

ClassA.prototype.name = "nomad";
ClassA.prototype.sayName = function(){
	alert(this.name);
}

function ClassB()
}
ClassB.prototype = new ClassA(); //要确保调用构造函数没有任何参数。

ClassB.prototype.age = 23;
ClassB.prototype.sayAge = function(){
	alert(this.age);
}  

混合方式--- 对象冒充继承构造函数的属性,用原型链继承 prototype 对象的方法。

Js代码 
function ClassA(aName){   
    this.name = aName;   
}   
  
ClassA.prototype.sayName = function(){   
    alert(this.name);   
}   
  
function ClassB(aName,aAge){   
    ClassA.call(this,aName);   
}   
  
ClassB.prototype = new ClassA();   
  
ClassB.prototype.sayAge = function(){   
    alert(this.age);   
}  

function ClassA(aName){
	this.name = aName;
}

ClassA.prototype.sayName = function(){
	alert(this.name);
}

function ClassB(aName,aAge){
	ClassA.call(this,aName);
}

ClassB.prototype = new ClassA();

ClassB.prototype.sayAge = function(){
	alert(this.age);
}  
其他继承方式:

zInherit 库( http://www.nczonline.net/downloads ): 支持所有的现代浏览器( Mozilla 、 IE 、 Opera 、 Safari )及一些旧的浏览器( Netscape 4.x 、 IE 、 Mac )。(需要引入 zinherit.js (见附件))



zInherit 库给 Object 类添加了两个方法:

----inheritFrom(): 负责复制指定类的所有方法, 接受一个参数,即要复制的方法所属的类

----instanceOf(): instanceof 运算符的替代品

Js代码 
<script type="text/javascript" src="~/zinherit.js"></script>   
function ClassA(){   
}   
  
ClassA.prototype.name = "nomad";   
ClassA.prototype.sayName = function(){   
    alert(this.name);   
}   
  
function ClassB(){   
}   
  
ClassB.prototype.inheritFrom(ClassA);    
  
ClassB.prototype.age = 23;   
ClassB.prototype.sayAge = function(){   
    alert(this.age);   
}  

<script type="text/javascript" src="~/zinherit.js"></script>
function ClassA(){
}

ClassA.prototype.name = "nomad";
ClassA.prototype.sayName = function(){
	alert(this.name);
}

function ClassB(){
}

ClassB.prototype.inheritFrom(ClassA); 

ClassB.prototype.age = 23;
ClassB.prototype.sayAge = function(){
	alert(this.age);
} 



xbObjects: 为 JavaScript 提供更强的面向对象范型,不止支持继承,还支持方法的重载和调用超类方法的能力。

(xbObjects.js见附件)



几个方法:

--registerClass(className, parentClassName):参数以字符串形式传递,如父类不明确,可以只用第一个参数

--defineClass(className, prototype_func):className为字符串形式的类名,prototype_func为函数指针(函数名)

--parentMethod(method,args...):接受任意多个参数,但第一个参数总是要调用的父类方法的名字(该参数必须是字符串,而不是函数指针),所有其他参数都被传给父类的方法。

---

Js代码
//1,必须注册类  
_classes.registerClass("Polygon");  
 
function Polygon(iSides) {  
    //2,在构造函数内调用defineClass()方法  
    _classes.defineClass("Polygon", prototypeFunction);  
    //3,  
    this.init(iSides);  
     
   //该函数用于初始化对象的所有属性和方法  
    function prototypeFunction() {  
      
        Polygon.prototype.init = function(iSides) {  
            this.parentMethod("init");  
            this.sides = iSides;              
        };  
      
        Polygon.prototype.getArea = function () {  
            return 0;  
        };      
      
    }  
}  
 
_classes.registerClass("Triangle", "Polygon");  
 
function Triangle(iBase, iHeight) {  
 
    _classes.defineClass("Triangle", prototypeFunction);  
      
    this.init(iBase,iHeight);  
      
    function prototypeFunction() {  
        Triangle.prototype.init = function(iBase, iHeight) {  
            this.parentMethod("init", 3);  
            this.base = iBase;  
            this.height = iHeight;  
        };  
          
        Triangle.prototype.getArea = function () {  
            return 0.5 * this.base * this.height;  
        };      
    }  
      
}  
 
_classes.registerClass("Rectangle", "Polygon");  
 
function Rectangle(iLength, iWidth) {  
 
    _classes.defineClass("Rectangle", prototypeFunction);  
      
    this.init(iLength, iWidth);  
      
    function prototypeFunction() {  
        Rectangle.prototype.init = function(iLength, iWidth) {  
            this.parentMethod("init", 4);  
            this.length = iLength;  
            this.width = iWidth;  
        }  
      
       Rectangle.prototype.getArea = function () {  
            return this.length * this.width;  
       };      
          
    }  

分享到:
评论
1 楼 yangdong 2009-01-13  
引用别人的文章内容时应该明确说明的。

相关推荐

    Java Script网页特效实例大全

    在"Java Script网页特效实例大全"中,我们能够找到一系列关于JavaScript特效的实践案例,帮助开发者提升网页交互性和视觉吸引力。 JavaScript的主要特点包括: 1. **解释型语言**:JavaScript代码不需要预编译,...

    java script 学习笔记

    * JavaScript 代码使用 `&lt;script&gt;` 标签包含,类型可以是 `text/javascript` 或 `language="javascript"`,但后者已经不再推荐使用。 * JavaScript 代码可以放在 HTML 文件的 `&lt;head&gt;` 或 `&lt;body&gt;` 部分,但如果放在...

    Java Script 经典封装

    以上就是关于“Java Script 经典封装”主题中涉及的一些核心知识点,它们是JavaScript开发中实现封装和高效代码组织的关键。通过理解和熟练运用这些概念,开发者可以编写出更加模块化、可维护的代码,提高代码质量。

    Java Script实例教程

    3. prototype和继承:通过原型链实现对象间的继承,`__proto__`属性指向父对象,`Object.create()`方法用于创建新对象并指定其原型。 三、DOM操作 1. DOM(文档对象模型)是HTML或XML文档的结构表示,JavaScript...

    java script 完全解析

    JavaScript 中的对象是通过原型链实现继承的。每个对象都有一个原型,当访问一个对象的属性或方法时,如果该对象本身没有,则会沿着原型链查找。 ```javascript function Person(name) { this.name = name; } ...

    java script教学范本

    本Java Script教学范本旨在提供一个全面而详尽的学习资源,帮助初学者和有一定基础的开发者深入理解和掌握JavaScript语言。JavaScript语法基于ECMAScript规范,它支持函数式、面向对象和命令式等多种编程范式,使其...

    Java Script精彩实例教程

    "Java Script精彩实例教程"是一本专为初学者设计的资源,它提供了丰富的实例来帮助读者理解和掌握JavaScript的基础及进阶概念。 在JavaScript的学习过程中,实例是最有效的教学工具之一。通过实际操作,你可以更好...

    Java Script 经典教程(九)——JavaScript完全网页教程

    理解原型、构造函数和继承机制是实现面向对象编程的关键。 此外,JavaScript还提供了异步编程的能力,如回调函数、Promise和async/await。这使得处理耗时操作(如网络请求)变得更加方便,避免了阻塞主线程导致的...

    Java Script 经典教程(三)——java script 专业设计

    ES6引入的类(class)语法糖使得面向对象编程更加直观,但其实质仍然是基于原型的继承。理解原型链和原型对象对于深入掌握JavaScript至关重要。 数组是处理多个值的数据结构。JavaScript提供了丰富的数组方法,如`...

    Java Script开发指南

    它在浏览器端运行,赋予网页动态功能,能够与用户进行交互,改变页面内容,处理数据,甚至实现复杂的动画效果。JavaScript是Web开发中的三大核心技术之一,另外两个是HTML和CSS。 本“JavaScript开发指南”将引领你...

    java script

    随着技术的发展,ES6(ECMAScript 2015)及以后的新特性,如箭头函数、模板字符串、let和const、解构赋值、模块系统(import/export)、类和继承等,也是现代JavaScript开发的重要组成部分。同时,学习如何使用调试...

Global site tag (gtag.js) - Google Analytics