发个JS练手作品,简单的OO封装

xingqiliudehuanghun 2011-07-22 01:47:58
最近翻书复习了下基础知识,感觉书上的面向对象的例子用起来不是很顺手
所以自己改了下,纯粹练手,有意见的请拍砖,当然最好能给出更好的例子。
var $class = (function(){       
var guid = 0,
classMap = {},
caller = null,
callStack = [];

return {
create : createClass
}

//------------------------[辅助函数部分]------------------------

/**
* 创建新类.
* @param {constructor}superClass 超类构造器,该类必须由$class.create创建
* @param {Json}proto 类原型
* @return {constructor}
*/
function createClass(superClass, proto){
var isSuperValid = superClass instanceof Function
&& superClass.prototype
&& superClass.prototype.init instanceof Function;

superClass = isSuperValid ? superClass : null;

var superProto = superClass ? superClass.prototype : null;

//定义类构造函数
var klass = function() {
var args = [].slice.call(arguments);

//执行父类构造函数.
if(superClass){
superClass.apply(this, args);
}

//若自己的原型中有init方法,执行init
if(klass.prototype.hasOwnProperty('init')){
klass.prototype.init.apply(this, args);
}
};

//定义类原型
var klassProto = getClassProto(superProto, proto);
klassProto.constructor = klass;
klass.prototype = klassProto;

//返回类
return klass;
}

/**
* 获取类原型.
* @param {json}superProto 超类原型
* @param {Json}overwrites 需要重写方法
* @return {json}
*/
function getClassProto(superProto, overwrites) {
var i, F, proto, classId = getGuid();

if(superProto){
F = function(){};
F.prototype = superProto;
proto = new F();
}else{
proto = getDefaultProto();
}

//用overwrites中方法覆盖原型中的方法
for(i in overwrites){
if(overwrites.hasOwnProperty(i)){
proto[i] = overwrites[i];
}
}

//修复IE中for in不能遍历toString、valueOf等属性的Bug
if(document.all){
var len, method, methods = ['toString', 'valueOf'];
for(i=0, len = methods.length; i < len; i++){
method = methods[i];
if( overwrites.hasOwnProperty(method) ){
proto[method] = overwrites[method];
}
}
}

//注册类关系
proto.classId = classId;
regClass(proto, superProto);

//确保原型中含有必要的原型方法
addMastHasMethods(proto);

return proto;
}

/**
* 获取默认原型.
* @return {json}
*/
function getDefaultProto(){
return {
init : function(){},
callSuper : callSuper
};
}

/**
* 调用超类方法.
* @param {String}methodName 方法名
* @return
*/
function callSuper(methodName){
caller = (caller === null ? this : caller);

var curClsId = callStack.length > 0
? callStack[callStack.length - 1]
: this.classId;

var args = [].slice.call(arguments, 1),
parent = getParent(curClsId),
ret;

if(parent && parent[methodName]){
callStack.push(parent.classId);

try{
ret = parent[methodName].apply(caller, args);
}catch(e){
alert(e);
}

callStack.pop();
}

//调用完毕后将调用上下文清空
if(callStack.length === 0){
caller = null;
}

return ret;
}

/**
* 将类信息注册到类记录表中.
* @param {json}proto 类原型.
* @param {json}parent 超类原型
*/
function regClass(proto, superProto){
var classId = proto.classId;

classMap[classId] = {
id : classId,
proto : proto,
parent: superProto
};
}

/**
* 检查原型链中是否有必须要实现的方法,没有的话,向原型中添加.
* @param {json}proto
*/
function addMastHasMethods(proto){
var i, dftProto = getDefaultProto();
for(i in dftProto){
if(dftProto.hasOwnProperty(i) && !proto[i]){
proto[i] = dftProto[i];
}
}
}

/**
* 获取guid.
* @return {int}
*/
function getGuid(){
return guid++;
}

/**
* 获取超类原型.
* @param {int}classId 类ID
* @return {json} 超类原型, 若存在返回null.
*/
function getParent(classId){
var record = classMap[classId];
return record ? record.parent : null;
}
})();

var Man = $class.create(null, {
init : function(cfg){
this.name = cfg.name;
this.age = cfg.age;
},

say : function(){
alert('my name is:' + this.name + ", " + this.age);
},

toString : function(){
return (
'name: ' + this.name
+ ', age: ' + this.age
);
}
});

var Student = $class.create(Man, {
init : function(cfg){ //执行此方法前会自动调用Man.init
this.stuNum = cfg.stuNum;
},

say : function(){
this.callSuper('say'); //调用父类方法
alert("i'm a student, my student number is " + this.stuNum);
},

toString : function(){
return (
this.callSuper('toString')
+ ', stuNum: ' + this.stuNum
);
}
});

window.onload = function(){
var m1 = new Man({name : '张三', age: 20}),
s1 = new Student({
name : '王五',
age : 22,
stuNum : 'no-1'
});

m1.say();
s1.say();
alert(m1.toString() + "\n" + s1.toString());
};
...全文
989 53 打赏 收藏 转发到动态 举报
写回复
用AI写文章
53 条回复
切换为时间正序
请发表友善的回复…
发表回复
流云细水 2013-03-12
  • 打赏
  • 举报
回复
看不懂……楼主有好的JS 书没,有基础和例子练习的,望推荐
异域风景 2012-02-27
  • 打赏
  • 举报
回复
表示很钦佩,有注释就更好了
h123hu 2012-02-27
  • 打赏
  • 举报
回复
表示看不懂,路还很长啊。。。。。。。。。
web_hsj 2012-02-26
  • 打赏
  • 举报
回复
向老鸟看齐!
aihua17 2012-02-23
  • 打赏
  • 举报
回复
COPY分析一下
马尾 2012-02-23
  • 打赏
  • 举报
回复
JS 的oo就是一种技巧!!
水很深!!新人头痛中丫!
szc108 2011-08-09
  • 打赏
  • 举报
回复
学习呀。JS的OO不好理解呀
yunpeijiao 2011-08-08
  • 打赏
  • 举报
回复
厉害啊!不错的
曹西 2011-08-05
  • 打赏
  • 举报
回复
向老鸟看齐,顶楼主
曹西 2011-08-05
  • 打赏
  • 举报
回复
留下脚印,copy
1988_1989 2011-08-05
  • 打赏
  • 举报
回复
看不太懂,但是还是认真看完了,
ytx98 2011-08-05
  • 打赏
  • 举报
回复
mark & up

留备以后学习
q198708wyp 2011-08-04
  • 打赏
  • 举报
回复
楼主强大
henghe98 2011-08-03
  • 打赏
  • 举报
回复


(function(){
var Base = window.Base = Base || {
///summary: 静态方法,创建抽象类
create: function () {
return function () {
this.initialize.apply(this, arguments);
}
},
///summary: 静态方法,实现继承,允许重载
extend: function () {
if (1 == arguments.length) {
for (var p in arguments[0]) this[p] = arguments[0][p];
return this;
};
for (var p in arguments[1]) arguments[0][p] = arguments[1][p];
return arguments[0];
},
///summary: Cookie类
Cookie: function () {
var Cookie = Base.create();
Cookie.prototype = {
initialize: function () { },
///写cookie
setCookie: function (name, value) {
var date = new Date();
date.setTime(date.getTime() + 30 * 24 * 3066 * 1000);
document.cookie = name + "=" + value + ";expires=" + date.toGMTString()
},
///读cookie
getCookie: function (name) {
var CookieArray = document.cookie.split(";");
for (var i = 0; i < CookieArray.length; i++) {
var arr = CookieArray[i].split("=");
if (arr[0] == name) {
return arr[1];
break;
}
}
},
///清除cookie
clearCookie: function (name) {
document.cookie = name + "=''; expires=Thu, 01-Jan-70 00:00:01 GMT";
}
}
return new Cookie();
}
};
})();

laodap1 2011-08-02
  • 打赏
  • 举报
回复
看不懂啊看不懂。。。
  • 打赏
  • 举报
回复
不知道js面向对象是不是真的大势所趋
qingYun1029 2011-07-31
  • 打赏
  • 举报
回复
livetiancao 2011-07-30
  • 打赏
  • 举报
回复
牛人呀·····
马老虎 2011-07-28
  • 打赏
  • 举报
回复
厉害。oo确实使用很方便。
oo 再加上VS2010,那真是完美了






-----------------------------

新版老虎插件即将登场:
豪情 2011-07-27
  • 打赏
  • 举报
回复
楼主写点注释啊,要不新手看不懂。
加载更多回复(30)

87,902

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧