类的封装 要干的事情如下
类
实际上就是一个 function
同时也是这个类的构造方法
可以使用 new 创建该类的实例
new 出的对象 有属性 有方法
属性和方法性质不同 因此定义的方式也不同
—— 实际上方法是一种特殊形式的属性
属性
每个实例单独所有 多个实例之间互不影响
因此要在构造方法中初始化实例的属性
—— 每次执行 new 时构造方法都会执行 会产生新的属性
—— 在其中定义方法当然也会 但不推荐 耗内存
方法
所有实例共有 创建多个实例不会产生新的 function
因此要在类的 prototype 中定义实例的方法
—— prototype 中的方法会被所有实例共有
—— 在其中定义属性当然也会 但不推荐 除非你知道自己在做什么
至于 private 算了吧
JavaScript 里没 private 硬要实现的话虽然也能 但是有点不伦不类
按照惯例 在属性或方法名前加一个下划线 声明为私有
外面看见这个不要动 假装没看见就好了
至于 static 这个容易
var Class = function() {};
Class.field = "";
Class.method = function() {};
没必要多说
单例
更不用费什么劲了
var Singleton = {
field: "",
method: function() {
}
};
命名空间 这个很有必要 尤其是在复杂的应用中
不过现在这个不是重点 日后详谈
原则
简单
高效
JavaScript 就是 JavaScript 而不是别的什么
—— 不要觉得 Java 或其它语言有什么 JavaScript 就该有什么
或许使用各种变态的方式可以实现 但很别扭 更不优雅
终于 到了 正题
偶然看见了 [url=http://wmingjian.iteye.com/blog/438211]alzui类封装的演化过程[/url]
以前也曾经干过类似的事情 但是用了好多代码
就没想过这件事情可以这么简单
仔细的研究了代码 佩服得不得了
不过貌似演化的最终结果有冗余的代码
实在没办法理解是否作者更深远的意图
在原文下提了 暂时还没得到作者的回复
下面是按照个人想法对作者最终版本的简化
貌似 挺好 没有问题
function _class(className, classImp){
var clazz = function(){
this._init.apply(this, arguments);
};
window[className] = clazz;
classImp.apply(clazz.prototype);
}
其实演化还可以继续的
1. 干掉了那个傀儡 并改用 constructor
因为那个傀儡实际上也没什么用
而 _init 是 Java 的 而且是见不得人的
constructor 才是 JavaScript 的
JavaScript 内置的所有的类的对象 都有constructor属性
指向类的本身 详见本文末尾测试代码
window.$Class = function(name, SRC) {
var src = new SRC();
window[name] = src.constructor;
window[name].prototype = src;
};
定义类
// define Class
$Class("Guy", function() {
this.constructor = function(name) {
this.name = name;
this.friends = [];
};
this.makeFriendWith = function(guy) {
this.friends.push(guy.name);
};
});
2. 再省掉一步 用 JSON 的格式定义类 更直观
或许这个可以叫做 final 版了 没办法再简单了
window.$Class = function(name, src) {
src.constructor.prototype = src;
window[name] = src.constructor;
};
定义类
$Class("Guy", {
constructor: function(name) {
this.name = name;
this.friends = [];
},
makeFriendWith: function(guy) {
this.friends.push(guy.name);
}
});
测试
适用于以上两种方式
要用到 JSON2
Firefox 已内置 其它浏览器未知 sb-ie 肯定没有
[url=http://www.json.org/json2.js]json2.js[/url]
测试代码
var minglq = new Guy("MingLQ");
var luoluo = new Guy("Luoluo");
minglq.makeFriendWith(luoluo);
luoluo.makeFriendWith(minglq);
var ____ = "--------------------------------";
alert([
JSON.stringify(minglq),
JSON.stringify(luoluo),
____,
"minglq.friends !== luoluo.friends:\n " + (minglq.friends !== luoluo.friends),
"minglq.makeFriendWith === luoluo.makeFriendWith:\n " + (minglq.makeFriendWith === luoluo.makeFriendWith),
____,
"minglq instanceof Guy:\n " + (minglq instanceof Guy),
"luoluo.constructor === Guy:\n " + (luoluo.constructor === Guy),
____,
"Guy:\n" + Guy.toString()
].join("\n"));
测试结果
{"name":"MingLQ","friends":["Luoluo"]}
{"name":"Luoluo","friends":["MingLQ"]}
--------------------------------
minglq.friends !== luoluo.friends:
true
minglq.makeFriendWith === luoluo.makeFriendWith:
true
--------------------------------
minglq instanceof Guy:
true
luoluo.constructor === Guy:
true
--------------------------------
Guy:
function (name) {
this.name = name;
this.friends = [];
}
详见 [url=http://gist.github.com/iwill]http://gist.github.com/iwill[/url]