JavaScript的写类方式(5)
这篇我们看看各个JS库的写类方式,这也是写类系列的最后一篇。
1,Prototype的写类方式
Prototype中使用Class.create方法,如下
//类名Person var Person = Class.create(); // 通过原型重写来定义Person Person.prototype = { initialize : function(name) { this.name = name; }, getName : function() { return this.name; }, setName : function(name) { this.name = name; } } // 创建对象 var p = new Person("jack"); console.log(p.constructor == Person);//false
initialize完成对象的初始化(相当于构造函数,必不可少),方法依次往下写即可。
有个问题,但是p.constructor == Person却为false,这正是Prototype库一个小缺陷。原因是重写了Person的原型。为了使constructor能指向正确的构造器,只需在原型重写时维护好constructor属性即可。
Person.prototype = { constructor : Person, // 注意这句将修复constructor属性 initialize : function(name) { this.name = name; }, getName : function() { return this.name; }, setName : function(name) { this.name = name; } }
2,Dojo的写类方式
dojo中用dojo.declare方法来定义一个类。dojo.declare有三个参数
参数1:类名className
参数2:继承的类superclass
参数3:构造器,方法props
单纯的定义一个类实际只需传第一,三两个参数。因为这里只讨论如何定义一个类,不讨论继承。
// 定义类名 var className = "Person"; // 定义构造器及方法 var proto = { constructor : function(name){this.name=name;}, getName : function(){ return this.name;}, setName : function(name){ this.name = name;} } // 定义类Person dojo.declare(className,null,proto); // 创建一个对象 var p = new Person("tom"); console.log(p.getName());//tom p.setName("jack"); console.log(p.getName());//jack // 测试instanceof及p.constructor是否正确指向了Person console.log(p instanceof Person);//true console.log(p.constructor === Person);//true
3,Ext的写类方式
Ext中用Ext.extend来定义一个类(当然它更多用来扩展一个类),Ext整个框架各种控件如Panel,MessageBox等都是用Ext.extend方法来扩展。这里仅仅用它来定义一个最简单的类。
这里只需传两个参数即可,第一个参数是根类Object,第二个是原型。比较特殊的是,如果单纯的定义一个类,那么第一个参数永远传Object即可。
/** * Person类 * @param {Object} name */ var Person = Ext.extend(Object,{ constructor : function(name) {this.name = name;}, setName : function(name) {this.name = name;}, getName : function() {return this.name;} }); // 创建一个对象 var p = new Person("Lily"); console.log(p.getName());//Lily p.setName("Andy"); console.log(p.getName());//Andy // 测试instanceof及p.constructor是否正确指向了Person console.log(p instanceof Person);//true console.log(p.constructor == Person);//true
4,YUI的写类方式
//定义包名 YAHOO.namespace("test"); // 定义类 YAHOO.test.Person = function(name) { this.name = name; } YAHOO.test.Person.prototype.setName = function(name){ this.name = name;} YAHOO.test.Person.prototype.getName = function(){ return this.name;} // 创建一个对象 var p = new YAHOO.test.Person("jack"); console.log(p.getName());//jack p.setName('tom'); console.log(p.getName());//tom // 测试instanceof及p.constructor是否正确指向了YAHOO.test.Person console.log(p instanceof YAHOO.test.Person); console.log(p.constructor == YAHOO.test.Person);
可以看出除了多了包名,与原始的 构造函数+原型 方式 并无区别。
5,Mootools的写类方式
mootools是被设计成非常紧凑的,模块化的,面向对象的JS库。mootools中写类用Class类。导入后我们写类时只需要用Class就行了。
/** * Person类 * @param {Object} name */ var Person = new Class({ initialize: function(name){ this.name = name; }, setName : function(name) { this.name = name; }, getName : function() { return this.name; } }) // new一个对象 var p = new Person("jack"); // 测试set,get方法 console.log(p.getName());//jac p.setName('andy'); console.log(p.getName());//andy // 测试instanceof及p.constructor是否正确指向了Person console.log(p instanceof Person); //true console.log(p.constructor == Person); //true
可以继续阅读: