JS中class的实现方式,另模拟dojo.declare

首先写一个简单的类。

function Animal(nickName){
    this.getNickName = function(){return nickName};
}
Animal.prototype.canMiaomiao=false;
Animal.prototype.eat=function(){console.log("animal eat");};
Animal.prototype.sleep=function(){console.log("animal sleep");};

上面实现了一个普通动物的类。nickName为其私有域,canSpeak为公有域。此类还有三个方法 getNickName, eat, sleep。

然后写一个子类。

function Cat(nickName, color) {
    this.superClass(nickName);
    this.getColor=function(){return color;};
}
Cat.prototype=new Animal();
Cat.prototype.constructor=Cat;
Cat.prototype.superClass=Animal;
Cat.prototype.canMiaomiao=true;
Cat.prototype.eat=function(){this.superClass.prototype.eat.call(this); console.log('cat eat');};
Cat.prototype.catchMouse=function(){console.log('catch mouse');};

Cat继承Animal,多了一个私有域color,多了新方法catchMouse,重写了方法eat,在eat中还调用了父类中的方法。运行下面代码,看发生了什么。

var a = new Animal('animal');
a.eat();
a.sleep();
a.getNickName();

var b = new Cat('cat','black');
b.eat();
b.catchMouse();
b.sleep();
b.getColor();
b.getNickName();

上面都是JS语法里面提供的方法。但这种方法只提供了单继承。如果想实现多继承,那需要引入新的方法mixin。在dojo中,mixin就是将一个object中的属性全部复制到另一个object。假设有两个父类A,B,现在需要设计一个子类,同时继承A和B,那么可以将A和B的属性全部mixin到C中,也可以C继承A后再minxin B。Dojo便使用了此方法实现多继承。

很多JS框架,都为了更好的结构化,模拟java似的面向对象。在java中,初始化一个类使用defineClass。dojo则设计了dojo.declare这一方法来声明一个类。下面的代码便定义了我们JS中的defineClass,虽然它只实现了单继承,但从中可见一斑。

// 传入参数为JSON, JSON中包含的properties如下。
// className: /*String*/ 
// extend: /*function*/
// constructor: /*function*/
// methods and fields: /*properties*/
// 下面代码不考虑容错性。

function defineClass(/*JSON*/data) {
    var className = data.className;
    var constructor = data.constructor || function(){};
    var superClass = data.extend || Object;
    var proto = new superClass();

    for (var property in data) {
        proto[property] = data[property];
    }
    proto.constructor = constructor;
    proto.superClass = superClass;
    proto.className = className;
    constructor.prototype=proto;

    window[className] = constructor;
}

有了以上这个简单的defineClass,我们可以换一种方式来动态的加载Animal和Cat类。

var AnimalClass = {
    className:'Animal',
    constructor: function(nickName){
                    this.getNickName = function(){return nickName};
                },
	extend:null,
	canMiaomiao:false,
	eat:function(){console.log("animal eat");},
	sleep:function(){console.log("animal sleep");}
};
defineClass(AnimalClass);
var CatClass = {
    className:'Cat',
    constructor: function(nickName, color) {
                    this.superClass(nickName);
                    this.getColor=function(){return color;};
                },
	extend:Animal,
	canMiaomiao:true,
	eat:function(){this.superClass.prototype.eat.call(this); console.log('cat eat');},
	catchMouse:function(){console.log('catch mouse');}
};
defineClass(CatClass);

var a = new Animal('animal');
var b = new Cat('cat');

以上只是简单的defineClass。Dojo的多继承比这要复杂很多,比如如何调用父类的方法。但是原理是非常相近的。这里就不再仔细分析了。如果有问题,请留言。

 

转载于:https://my.oschina.net/xpbug/blog/67558

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值