创建javascript的类继承体系

我觉得javascript是一种神奇的语言,随着逐步了解,会发现很多神奇的用法。

javascript是以函数为第一成员的解释性语言,也是面向过程的语言,但却可以神奇地演变成支持类型和对象。这就要提到原型(prototype)的概念。每个函数都有原型,而原型本身是一个对象,它包含这个函数对象的成员变量和成员方法。或者说,若把函数当成类型看待的话,原型就是承载成员变量和成员函数的东西。所以对象是没有原型的,而函数(类)本身也不能承载成员变量和成员函数。

像java 一样,javascript也有关键字this,它指向当前位置所属的作用域,而此作用域是一个对象,默认情况下,this指向window,即当前窗口对象。

function Func1(){
    //this指向window
	console.log('this is ' + this);
	if(arguments.length > 0){
		return 'My first argument is ' + arguments[0];
	}else{
		return ' I have no argment ';
	}
}

当this是处在一个类(通过函数的原型添加成员,或在函数体内通过this.添加成员)中时,this就是指通过此类创建的对象。

//创建类的三种方式,this都指向所在类创建的对象,而非window.
function ClassA(){
	console.log('this is ' + this);
	this.name = 'ClassA';
	this.run = function(){
		return 'My name is ' + this.name;
	};
	this.myFunc = function(){};
}

function ClassB(){
	console.log('this is ' + this);
	name = 'ClassB';
	return {
		run:function(){
			return 'My name is ' + this.name;
		}
	}
}

function ClassB(){}
ClassB.prototype.run = function(){
    console.log('this is ' + this);
}

javascript中对象的成员可以访问哈希表一样访问,这样的灵活性使对象的成员扩展变得很灵活。方法Object.assign可以用来扩展成员。

基于这三个语言特性,我们在不使用新版的class关键字的情况下,建立javascript的类型体系。

//定义最顶级类,用于js继承基类
function Class() { }
//顶级类方法默认空方法(当前还不是真正的构造函数)
Class.prototype.constructor = Class;
Class.extend = function (def) {
    var oc = Object.prototype.constructor;
    var subClass = {};
    if(def.constructor != oc){//定义了自己的构造函数
        subClass = def.constructor;
    } else {//若未定义自己的构造函数,则使用父类构造函数
        subClass = this.apply(this,def);
    }
    
    //原型对象
    var proto = new this();
    for (var n in def) {
        proto[n] = def[n];
    }
    subClass.prototype = proto;
    //此为父类原型
    var superClass = this.prototype;
    subClass.superClass = superClass;
    //赋给这个新的子类同样的静态extend方法
    subClass.extend = this.extend;
    return subClass;
};

类型为Class类体系中的顶层类,可以通过extend方法来定义子孙类.

//类Animal 继承自Class
var Animal = Class.extend({
    action:'walk',
    constructor: function (name) {
        Animal.superClass.constructor.call(this);
        this.name = name || "Animal";
    },
    eat: function (food) {
        console.log("Father." + this.name + '正在吃:' + food);
    },
    sleep: function () {
        console.log("Father." + this.name + '正在睡觉!');
    }
});

// 类Cat继承自Animal
var Cat = Animal.extend({
    love:'fish',
    constructor: function () {
        Cat.superClass.constructor.call(this,"Cat");
        console.log('Cat constructor');
    },
    eat: function (food) {
        console.log("SubClass." + this.name + '正在吃:' + food);
        Cat.superClass.eat.call(this, food);
    },
    sleep: function () {
        console.log("SubClass." + this.name + '正在睡觉!');
        Cat.superClass.sleep.call(this);
    }
});

可以通过下面测试来判断继承关系,以及对覆盖方法后对父类相同方法的调用。

var cat = new Cat();
console.log(cat.name);
console.log(cat.eat('fish'));
console.log(cat.sleep());
console.log(cat instanceof Animal); // true
console.log(cat instanceof Cat); //true

参考:Extjs3.4中类型扩展。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

WalsonTung

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值