JavaScript中的Java式继承

JavaScript中的Java式继承

在面向对象编程中,类是核心部分。在JavaScript面向对象编程中没有提供定义类的方式(java提供了class关键字来定义一个类),但是在JavaScript中可以通过其它方式来模拟类。下面我们就来讲一下怎样在JavaScript中模拟类。注:以下内容是学习《JavaScript 权威指南 第六版》9.3节的学习笔记。

如果你有过java或其它强类型面向对象语言的开发经营,在你的脑海中,类成员的模样可能是这样:
实例字段:它们是基于实例的属性和变量,用以保存独立对象的状态。
实例方法:它们是 类的所有实例共享的方法,由每个独立的实例调用。
类字段(相当于静态字段):这些属性是属于类的,而不是属于类的某个实例。
类方法(想当于静态方法):这些方法是属于类的,而不是属于类的某个实例。
为了便于理解以上内容,我们用java代码实现一个 表示值范围的类,然后再用JavaScript来实现。
表示值范围的类(java版)
package cn.com.hitsoftware;

import java.util.ArrayList;
import java.util.Arrays;

public class Range {
	//数据成员(属性)
	private int from;	//"范围对象"的起始位置
	private int to;		//"范围对象"的开始位置
	
	//构造函数
	public Range(int from,int to) throws Exception{
		if(from<Range.minFrom || to>Range.maxTo)
			throw new Exception(from+"~"+to+"超出了对象所能表示的范围");
		this.from = from;
		this.to = to;
	}
	
	//数据方法
	/**
	 * x在范围之内返回true,否则fasle
	 */
	public boolean includes(int x){
		return from<=x && x<=to;
	}
	/**
	 * 返回范围内的所有数据
	 */
	public ArrayList<Integer> foreach(){
		ArrayList<Integer> array = new ArrayList<Integer>();
		for(int i=from;i<to;i++)
			array.add(i);
		return array;
	}
	/**
	 * 返回表示这个范围的字符串
	 */
	public String toString(){
		return "("+from+"..."+to+")";
	}
	
	//(3)类字段
	public static final int minFrom = 1;	//"范围对象"的起始位置最小值
	public static final int maxTo = 1000;	//"范围对象"的起始位置最大值
	
	//(4)类方法
	/**
	 * 已数组中元素的最大值和最小值最创建一个"范围对象"
	 */
	public static Range getRangeByArray(int[] array) throws Exception{
		Arrays.sort(array);
		return new Range(array[0],array[array.length-1]);
	}
	
	public static void main(String [] args){
		try {
			Range r1 = new Range(1,1000); //(1)from、to就是 r1的实例字段,来标示每个实例独有的from和to(虽然是私有不能通过实例来访问)
			System.out.println(r1.toString());//(2)这里toString就是r1实例的方法 (
			
			int[] array = {2,2,1,64,44,90,12};
			Range r2 = Range.getRangeByArray(array);
			System.out.println(r2.toString());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
}



表示值范围的类(JavaScript版)
在JavaScript中模拟类需要用到JavaScrpt中的构造函数、原型对象和实例的的知识。这里对这个三个知识点进行简单的概括:
构造函数:构造函数为JavaScript定义了类名。添加到构造函数对象的属性就是类字段和方法(如果属性值是函数的话就是类方法)。
原型对象:原型对象上的属性和方法会被所有实例继承。属性会被类的当做实例字段来调用,方法会被类实例当做实例方法来调用。
这里插一句。共享属性和方法都放在原型对象上。每个实例独有的状态(对本例来讲就是from和to)都放在构造函数中,这样每次new 构造函数都会初始独有的状态。
实例对象:每个实例都是一个独立的对象。直接在实例上定义属性是不会为其它实例共享的。
//实现一个表示值范围的类
//定义个表示值范围的类
function Range(from,to){
    if(from<Range.minFrom || to>Range.maxTo)
        throw new TypeError(Range.minFrom+"~"+Range.maxTo+"超出了对象所能表示的范围");
    this.from = from;
    this.to = to;
}
//将需要共享的属性和方法放到原型对象上
//这样所有的实例都会共享原型对象上的属性和方法
Range.prototype = {
    constructor: Range,
    includes: function(x){
        return this.from<=x && x<=this.to;
    },
    foreach: function(){
        for(var x=this.from,a=[];x<=this.to;x++) a.push(x);
        return a;
    },
    toString: function(){ return '('+this.from+'...'+this.to+')'; }
}
//(3)类字段
Range.minFrom = 1;
Range.maxTo = 1000;

//(4)类方法
Range.getRangeByArry = function(array){
    array.sort(function(a,b){ return a-b });
    return new Range(array[0],array[array.length-1]);
}
console.log("测试一===========================");
var r1 = new Range(1,100);
console.log(r1.includes(4));
console.log(r1.foreach());
console.log(r1.toString());
console.log(r1.constructor === Range);

console.log("测试二===========================");
var r2 = Range.getRangeByArry([1,90,45,209,1,5,8,4]);
console.log(r2.includes(4));
console.log(r2.foreach());
console.log(r2.toString());//(2)这里toString()就是实例方法,从原型对象继承来的
console.log(r2.constructor === Range);
console.log("from:"+r2.from+"  to:"+r2.to);//(1)r2.from、r2.to就是实例字段,javascript中没有像java提供private关键字,所有我们能通过实例来访问

javascript没有private关键字将属性定义为私有,但是通过闭包可以模拟私有属性。通过ECMAScript 5的新特性可以实现java中的final关键字,让属性只读,不允许修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值