├── README.md
├── dist
├── Class.js
└── Utils.js
├── makefile
├── src
├── Class.js
└── Utils.js
├── test_browser.html
└── test_node.js
/README.md:
--------------------------------------------------------------------------------
1 | #BlxClass
2 |
3 | ##GitHub
4 | [https://github.com/bramblex/BlxClass](https://github.com/bramblex/BlxClass)
5 |
6 | ##简介
7 | 一个JavaScript面对对象的库,让你在JavaScript用上靠谱的面对对象特性。
8 |
9 | ##使用
10 | 将本项目中的 ```dist/Class.js``` 复制到你的项目下
11 |
12 | ###1. 在nodejs中使用
13 |
14 | ```JavaScript
15 | var Class = require('path/to/Class.js');
16 | var ClassA = Class('ClassA', Object);
17 | ```
18 |
19 | ###2. 在浏览器中使用
20 |
21 | ```Html
22 |
23 |
26 | ```
27 |
28 | ###3. 用RequireJS加载
29 | BlxClass 同时也符合AMD规范,可以用RequireJS加载
30 |
31 | ```JavaScript
32 | require(['path/to/Class.js'], function(Class){
33 | var ClassA = Class('ClassA', Object);
34 | });
35 | ```
36 |
37 | ##API
38 |
39 | ###1. Class( class\_name, parent\_class)
40 | Class函数接受两个参数返回一个新类,第一个参数是新类的命名,第二个参数是继承自哪个类。如果并没有继承自别的类,那么直接写Object就好了。
41 |
42 | ```JavaScript
43 | var ClassA = Class('ClassA', Object);
44 | var ClassB = Class('ClassB', ClassA);
45 | ```
46 |
47 | ###2. name
48 | 类的名字
49 |
50 | ```JavaScript
51 | var ClassA = Class('ClassA', Object);
52 | console.log(ClassA.name) // => ClassA
53 | var ClassB = Class('some name', ClassA);
54 | console.log(ClassB.name) // => some name
55 | ```
56 |
57 | ###3. parent
58 | 类的父类
59 |
60 | ```JavaScript
61 | var ClassA = Class('ClassA', Object);
62 | ClassA.parent === Object; // => true
63 | var ClassB = Class('ClassB', ClassA);
64 | ClassB.parent === ClassA; // => true
65 | ```
66 |
67 | ###4. method( method\_name, function )
68 | 定义方法,方法会被子类继承,并且能够重载。
69 |
70 | ```JavaScript
71 | var ClassA = Class('ClassA', Object)
72 | .method('constructor', function(){
73 | // 构造函数
74 | this.name = 'no name';
75 | })
76 | .method('constructor', function(name){
77 | // 重载构造函数
78 | this.name = name;
79 | })
80 | .method('run', function(){
81 | // 普通方法
82 | console.log('run');
83 | })
84 | .method('run', function(a,b){
85 | // 重载上面定义的run方法
86 | console.log('run a, b: ', a, b);
87 | })
88 | .method('run', '*', function(){
89 | // 其他任意参数的情况
90 | console.log(arguments);
91 | });
92 |
93 | var a = ClassA();
94 | var b = ClassA('Li Lei');
95 | console.log(a.name); // => no name
96 | console.log(b.name); // => Li Lei
97 | a.run(); // => run
98 | a.run(1,2); // => run a, b: 1 2
99 | a.run(4,5,6); // => [4,5,6]
100 | a.run(7,8,9,0,1,2,3); // => [7,8,9,0,1,2,3]
101 | ```
102 |
103 | ###5. classmethod( method\_name, function )
104 | 定义类方法,类方法不会被子类继承,也不能重载。
105 |
106 | ```JavaScript
107 | var ClassA = Class('ClassA', Object)
108 | .classmethod('run', function(){
109 | // 类方法
110 | console.log('class method run');
111 | });
112 |
113 | ClassA.run(); // => class method run
114 | ```
115 |
116 | ###6. extend( class\_name )
117 | 继承出新类。
118 |
119 | ```JavaScript
120 | var ClassA = Class('ClassA', Object);
121 |
122 | // 下面两种写法是等价的
123 | var ClassB = Class('ClassB', ClassB);
124 | var ClassB = ClassA.extend('ClassB');
125 | ```
126 |
127 | ###7. alias( alias\_name , method\_name )
128 | 给方法取别名
129 |
130 | ```JavaScript
131 | var ClassA = Class('ClassA', Object)
132 | .method('run', function(){
133 | // 普通方法
134 | console.log('run');
135 | });
136 |
137 | ClassA.alias('aliasRun', 'run');
138 |
139 | var a = ClassA();
140 | a.run(); // => run
141 | a.aliasRun(); // => run
142 | a.run === a.aliasRun; // => true
143 | ```
144 |
145 | ###8. uper( method\_name )
146 | 调用父类方法
147 |
148 | ```JavaScript
149 | var ClassA = Class('ClassA', Object)
150 | .method('run', function(){
151 | // 普通方法
152 | console.log('ClassA run');
153 | });
154 |
155 | var ClassB = ClassA.extend('ClassB')
156 | .method('run', function(){
157 | ClassB.uper('run').apply(this, arguments);
158 | console.log('ClassB run');
159 | });
160 |
161 | var ClassC = ClassB.extend('ClassC')
162 | .method('run', function(){
163 | ClassC.uper('run').apply(this, arguments);
164 | console.log('ClassC run');
165 | });
166 |
167 | var c = ClassC();
168 | a.run();
169 | // => ClassA run
170 | // => ClassB run
171 | // => ClassC run
172 | ```
173 |
--------------------------------------------------------------------------------
/dist/Class.js:
--------------------------------------------------------------------------------
1 |
2 | (function(__root__, __define__){
3 | var define = function define(dependencies, factory) {
4 |
5 | var factory = factory || dependencies;
6 | var dependencies = (Array.isArray(dependencies) && dependencies) || [];
7 |
8 | if ( typeof __define__ === 'function' && __define__.amd){
9 | __define__(dependencies, factory);
10 | } else if ( typeof __define__ === 'function' && __define__.cmd){
11 | __define__(dependencies, function(require, exports, module){
12 | module.exports = factory.apply(__root__, dependencies.map(function(m){
13 | return require(m);
14 | }));
15 | });
16 | } else if (typeof exports === 'object'){
17 | module.exports = factory.apply(__root__, dependencies.map(function(m){
18 | return require(m);
19 | }));
20 | } else{
21 | var name = document.currentScript.src.replace(/(^.*?)([^\/]+)\.(js)(\?.*$|$)/, '$2');
22 | name = name.replace('.min', '');
23 | __root__[name] = factory.apply(__root__, dependencies.map(function(m){
24 | return __root__[m.replace(/^.*\//, '')];
25 | }));
26 | }
27 | };
28 |
29 |
30 | define(['./Utils'], function(Utils){
31 |
32 | var named = function named(name, func){
33 | var code = func.toString();
34 | return '(' + code.replace(/(function\s+)(\w*?)\s*(\([\w, ]*?\))/m, '$1'+name+'$3') + ')';
35 | };
36 |
37 | var method = function method(name, argc, func){
38 | if (typeof arguments[1] === 'function'){
39 | var func = arguments[1];
40 | var argc = func.length;
41 | }
42 | else if (arguments[1] === '*' && typeof arguments[2] === 'function'){
43 | var func = arguments[2];
44 | var argc = '*';
45 | }
46 | else if (typeof arguments[1] === 'number' && typeof arguments[2] === 'function'){
47 | var func = arguments[2];
48 | var argc = arguments[1];
49 | }
50 | else {
51 | throw new Error('Define method Error!');
52 | }
53 |
54 | var this_class = this;
55 |
56 | if (name === 'constructor')
57 | name = '__constructor__';
58 |
59 | if(!this_class.prototype[name] || this_class.prototype[name]['__class__'] !== this_class){
60 | this_class.prototype[name] = eval(named(this_class.name+'_'+name, function(){
61 | var methods = this_class['__methods__'];
62 | var method = (methods && ( methods[name][arguments.length] || methods[name]['*'] ) ) || undefined;
63 | if (!method){
64 | method = this_class.parent.prototype[name];
65 | if (!method){
66 | err = Error('method not found!');
67 | err.stack = err.stack.slice(0, -2);
68 | throw err;
69 | }
70 | }
71 | return method.apply(this, arguments);
72 | }));
73 | this_class.prototype[name]['__class__'] = this_class;
74 | }
75 |
76 | if(!this_class.__methods__)
77 | this_class.__methods__ = {};
78 | if(!this_class.__methods__[name])
79 | this_class.__methods__[name] = {};
80 | this_class.__methods__[name][argc] = func;
81 |
82 | return this;
83 | }
84 |
85 | var classmethod = function classmethod(name, func){
86 | this[name] = eval(named(this.name+'_class_'+name, function(){
87 | return func.apply(this, arguments);
88 | }));
89 | this[name]['is_classmethod'] = true;
90 | return this;
91 | }
92 |
93 | var extend = function extend(name){
94 | return Class(name, this);
95 | };
96 |
97 | var alias = function alias(name, method){
98 | this.method(name, '*', this.prototype[method]);
99 | this.prototype[name]['is_alias_to'] = method;
100 | return this;
101 | };
102 |
103 | var upper = function upper(name){
104 | var this_class = this;
105 | if (name === 'constructor')
106 | name = '__constructor__';
107 | return this_class.parent.prototype[name];
108 | };
109 |
110 | var inspect = function inspect(){
111 | var this_class = this;
112 | var methods = Utils.attrs(this.prototype)['all']
113 | .map(function(method_name){
114 | var method = this_class.prototype[method_name];
115 | var method_class = method.__class__;
116 | var is_alias_to = method.is_alias_to;
117 | if (is_alias_to){
118 | var method_content = method_name + ' -> '+ is_alias_to;
119 | }
120 | else {
121 | var method_content = method_name;
122 | }
123 | if (this_class === method_class){
124 | return method_content;
125 | }
126 | else{
127 | return method_class.name + '::' + method_content;
128 | }
129 | });
130 | var methods_content = 'methods: \n'
131 | + Utils.indent(2, methods.join('\n'));
132 | var classmethods = Utils.attrs(this)['self']
133 | .filter(function(m){ return this_class[m]['is_classmethod'] || false; });
134 | var classmethods_content = 'classmethods: \n'
135 | + Utils.indent(2, classmethods.join('\n'));
136 | var content = Utils.indent(2, [classmethods_content, methods_content].join('\n\n'));
137 | return Utils.render(
138 | '[ Class <% class_name %> extend <% parent_class_name %>\n\n<% content %>\n]',
139 | {class_name: this.name, parent_class_name: this.parent.name, content: content});
140 | };
141 |
142 |
143 | var Class = function Class(name, parent){
144 | var parent = parent || Object;
145 |
146 | var child = eval(named(name, function(){
147 | var this_class = arguments.callee;
148 | var obj;
149 | if(this instanceof this_class){
150 | if (!!this_class.__sign__){
151 | delete this_class.__sign__;
152 | return;
153 | } else {
154 | obj = this;
155 | }
156 | }
157 | else{
158 | this_class.__sign__ = true;
159 | obj = new this_class();
160 | }
161 | obj.__class__ = this_class;
162 | this_class.prototype['__constructor__'].apply(obj, arguments);
163 |
164 | return obj;
165 | }));
166 |
167 | if (!!parent['parent'])
168 | parent.__sign__ = true;
169 | child.prototype = new parent();
170 | child.parent = parent;
171 |
172 | // function
173 | child.method = method;
174 | child.classmethod = classmethod;
175 | child.extend = extend;
176 | child.alias = alias;
177 | child.upper = upper;
178 | child.name = name;
179 | child.inspect = inspect;
180 |
181 | child.method('constructor', function(){
182 | if (child.upper('constructor'))
183 | child.upper('constructor').apply(this, arguments);
184 | });
185 |
186 | // init
187 | return child;
188 | };
189 |
190 | return Class;
191 | });
192 |
193 |
194 | })(this, typeof define !== 'undefined' && define);
195 |
--------------------------------------------------------------------------------
/dist/Utils.js:
--------------------------------------------------------------------------------
1 |
2 | (function(__root__, __define__){
3 | var define = function define(dependencies, factory) {
4 |
5 | var factory = factory || dependencies;
6 | var dependencies = (Array.isArray(dependencies) && dependencies) || [];
7 |
8 | if ( typeof __define__ === 'function' && __define__.amd){
9 | __define__(dependencies, factory);
10 | } else if ( typeof __define__ === 'function' && __define__.cmd){
11 | __define__(dependencies, function(require, exports, module){
12 | module.exports = factory.apply(__root__, dependencies.map(function(m){
13 | return require(m);
14 | }));
15 | });
16 | } else if (typeof exports === 'object'){
17 | module.exports = factory.apply(__root__, dependencies.map(function(m){
18 | return require(m);
19 | }));
20 | } else{
21 | var name = document.currentScript.src.replace(/(^.*?)([^\/]+)\.(js)(\?.*$|$)/, '$2');
22 | name = name.replace('.min', '');
23 | __root__[name] = factory.apply(__root__, dependencies.map(function(m){
24 | return __root__[m.replace(/^.*\//, '')];
25 | }));
26 | }
27 | };
28 |
29 | define(function(){
30 |
31 | var Utils = {};
32 |
33 | Utils.indent = (function(){
34 | var indentStr = function indentStr(n, s){
35 | var n = n || 0;
36 | var s = s || ' ';
37 | var str = '';
38 | for (var i=0; i').map(function(piece){
111 | var p = piece.split('<%');
112 | return (p[0] || '') + ((p[1] && hook(values[p[1].replace(/^\s*(\w+)\s*$/,'$1')])) || '');
113 | }).join('');
114 | };
115 |
116 | Utils.inspect = function inspect(obj, depth){
117 | var indent = Utils.indent;
118 | var inspect = Utils.inspect;
119 | var attrs = Utils.attrs;
120 |
121 | if (typeof depth !== 'number')
122 | var depth = 3;
123 |
124 | if ( obj && typeof obj.inspect === 'function'){
125 | return obj.inspect(depth);
126 | }
127 | var t = typeof obj;
128 | if (t === 'undefined' ){
129 | return 'undefined'
130 | }
131 | else if (t === 'boolean' || t === 'number'){
132 | return obj.toString();
133 | }
134 | else if (t === 'string'){
135 | return JSON.stringify(obj);
136 | }
137 | else if (t === 'function'){
138 | if (obj.name){
139 | return '[Function: ' + obj.name + ']';
140 | }
141 | else {
142 | return '[Function]';
143 | }
144 | }
145 | else if (t === 'object'){
146 | if (obj === null){
147 | return 'null'
148 | }
149 | else if (obj instanceof RegExp || obj instanceof Date){
150 | return obj.toString();
151 | }
152 | else if (obj instanceof Array){
153 | if (depth < 0){
154 | return '[Array]';
155 | }
156 | else if (obj.length <= 0){
157 | return '[]';
158 | }
159 | else {
160 | var content = obj.map(function(item){
161 | return inspect(item, depth-1);
162 | });
163 | var content_str = content.join(',\n');
164 | if (content_str.length < 80){
165 | content_str = content.join(', ');
166 | }
167 | return '[ ' + indent.skipFirstLine(2, content_str) +' ]';
168 | }
169 | }
170 | else{
171 | if (depth < 0){
172 | return '[Object]';
173 | }
174 | else {
175 | var keys = attrs(obj).self;
176 | if (keys.length <= 0){
177 | return '{}';
178 | }
179 | else {
180 | var content = keys.map(function(key){
181 | if (/[a-zA-Z_$][a-zA-Z-$0-9]*/.test(key)){
182 | var key_str = key;
183 | }
184 | else {
185 | var key_str = inspect(key);
186 | }
187 | return key_str + ': ' + inspect(obj[key], depth-1);
188 | });
189 | var content_str = content.join(',\n');
190 | if (content_str.length < 80){
191 | content_str = content.join(', ');
192 | }
193 | return '{ ' + indent.skipFirstLine(2, content_str) +' }';
194 | }
195 | }
196 | }
197 | }
198 | };
199 |
200 | Utils.color = (function(){
201 | var render = Utils.render;
202 | var colors = {
203 | 'bold' : [1, 22],
204 | 'italic' : [3, 23],
205 | 'underline' : [4, 24],
206 | 'inverse' : [7, 27],
207 | 'white' : [37, 39],
208 | 'grey' : [90, 39],
209 | 'black' : [30, 39],
210 | 'blue' : [34, 39],
211 | 'cyan' : [36, 39],
212 | 'green' : [32, 39],
213 | 'magenta' : [35, 39],
214 | 'red' : [31, 39],
215 | 'yellow' : [33, 39]
216 | };
217 | return function color(c, str){
218 | return render(
219 | '\u001b[<%left%>m<%str%>\u001b[<%right%>m',
220 | { left: colors[c][0], right: colors[c][1], str: str}
221 | )
222 | };
223 | })();
224 |
225 | Utils.surround = function surround(pair, str){
226 | var left = pair.substr(0, pair.length/2);
227 | var right = pair.substr(pair.length/2);
228 | return left + str + right;
229 | }
230 |
231 | Utils.merge = function merge(target, obj){
232 | var attrs = Utils.attrs;
233 | var result = {};
234 |
235 | var target_keys = attrs(target).self;
236 | var obj_keys = attrs(obj).self;
237 |
238 | target_keys.forEach(function(key){
239 | result[key] = target[key];
240 | });
241 | obj_keys.forEach(function(key){
242 | result[key] = obj[key];
243 | });
244 | return result;
245 | };
246 |
247 | Utils.kv = function(key, value){
248 | var obj = {};
249 | obj[key] = value;
250 | return obj
251 | }
252 |
253 | Utils.importScope = function importScope(name){
254 | return Utils.render(
255 | 'for (this.__inject_key__ in <%name%>){ eval("var "+this.__inject_key__+"="+"<%name%>"+"."+this.__inject_key__)}; delete this.__inject_key__;'
256 | ,{name: name}
257 | );
258 | };
259 |
260 | Utils.uniqueId = (function(){
261 | var count = 0;
262 | return function uniqueId(){
263 | return count++;
264 | }
265 | })();
266 |
267 | Utils.uniqueId.own = function(){
268 | return (function(){
269 | var count = 0;
270 | return function uniqueId(){
271 | return count++;
272 | }
273 | })()
274 | };
275 |
276 | Utils.equal = function equal(a, b){
277 | return (
278 | (typeof a === typeof b) && (
279 | (a === b) || (
280 | (typeof a.equal === 'function')
281 | && (!!(a.equal(b)))
282 | ) || (
283 | (a instanceof Array) && (b instanceof Array) && (Utils.equal.array(a, b))
284 | )
285 | )
286 | );
287 | };
288 |
289 | Utils.equal.array = function equalArray(a, b){
290 | return a.map(function(e, i){
291 | return [e, b[i]];
292 | }).reduce(function(last, item){
293 | return last && Utils.equal(item[0], item[1]);
294 | }, a.length === b.length);
295 | };
296 |
297 | return Utils;
298 | });
299 |
300 |
301 | })(this, typeof define !== 'undefined' && define);
302 |
--------------------------------------------------------------------------------
/makefile:
--------------------------------------------------------------------------------
1 |
2 | source_file = $(shell ls src/)
3 | objects = $(foreach o, $(source_file), $(subst .js, ,$(o)))
4 | target_files = $(foreach o, $(objects), dist/$(o).js)
5 | umdt = 'umdt'
6 |
7 | .PHONY: all
8 | all: dist $(target_files)
9 |
10 | dist:
11 | @mkdir -p dist
12 |
13 | $(target_files):dist/%.js:src/%.js
14 | umdt $< $@
15 |
16 | .PHONY: clean
17 | clean:
18 | rm -r dist
19 |
--------------------------------------------------------------------------------
/src/Class.js:
--------------------------------------------------------------------------------
1 |
2 | define(['./Utils'], function(Utils){
3 |
4 | var named = function named(name, func){
5 | var code = func.toString();
6 | return '(' + code.replace(/(function\s+)(\w*?)\s*(\([\w, ]*?\))/m, '$1'+name+'$3') + ')';
7 | };
8 |
9 | var method = function method(name, argc, func){
10 | if (typeof arguments[1] === 'function'){
11 | var func = arguments[1];
12 | var argc = func.length;
13 | }
14 | else if (arguments[1] === '*' && typeof arguments[2] === 'function'){
15 | var func = arguments[2];
16 | var argc = '*';
17 | }
18 | else if (typeof arguments[1] === 'number' && typeof arguments[2] === 'function'){
19 | var func = arguments[2];
20 | var argc = arguments[1];
21 | }
22 | else {
23 | throw new Error('Define method Error!');
24 | }
25 |
26 | var this_class = this;
27 |
28 | if (name === 'constructor')
29 | name = '__constructor__';
30 |
31 | if(!this_class.prototype[name] || this_class.prototype[name]['__class__'] !== this_class){
32 | this_class.prototype[name] = eval(named(this_class.name+'_'+name, function(){
33 | var methods = this_class['__methods__'];
34 | var method = (methods && ( methods[name][arguments.length] || methods[name]['*'] ) ) || undefined;
35 | if (!method){
36 | method = this_class.parent.prototype[name];
37 | if (!method){
38 | err = Error('method not found!');
39 | err.stack = err.stack.slice(0, -2);
40 | throw err;
41 | }
42 | }
43 | return method.apply(this, arguments);
44 | }));
45 | this_class.prototype[name]['__class__'] = this_class;
46 | }
47 |
48 | if(!this_class.__methods__)
49 | this_class.__methods__ = {};
50 | if(!this_class.__methods__[name])
51 | this_class.__methods__[name] = {};
52 | this_class.__methods__[name][argc] = func;
53 |
54 | return this;
55 | }
56 |
57 | var classmethod = function classmethod(name, func){
58 | this[name] = eval(named(this.name+'_class_'+name, function(){
59 | return func.apply(this, arguments);
60 | }));
61 | this[name]['is_classmethod'] = true;
62 | return this;
63 | }
64 |
65 | var extend = function extend(name){
66 | return Class(name, this);
67 | };
68 |
69 | var alias = function alias(name, method){
70 | this.method(name, '*', this.prototype[method]);
71 | this.prototype[name]['is_alias_to'] = method;
72 | return this;
73 | };
74 |
75 | var upper = function upper(name){
76 | var this_class = this;
77 | if (name === 'constructor')
78 | name = '__constructor__';
79 | return this_class.parent.prototype[name];
80 | };
81 |
82 | var inspect = function inspect(){
83 | var this_class = this;
84 | var methods = Utils.attrs(this.prototype)['all']
85 | .map(function(method_name){
86 | var method = this_class.prototype[method_name];
87 | var method_class = method.__class__;
88 | var is_alias_to = method.is_alias_to;
89 | if (is_alias_to){
90 | var method_content = method_name + ' -> '+ is_alias_to;
91 | }
92 | else {
93 | var method_content = method_name;
94 | }
95 | if (this_class === method_class){
96 | return method_content;
97 | }
98 | else{
99 | return method_class.name + '::' + method_content;
100 | }
101 | });
102 | var methods_content = 'methods: \n'
103 | + Utils.indent(2, methods.join('\n'));
104 | var classmethods = Utils.attrs(this)['self']
105 | .filter(function(m){ return this_class[m]['is_classmethod'] || false; });
106 | var classmethods_content = 'classmethods: \n'
107 | + Utils.indent(2, classmethods.join('\n'));
108 | var content = Utils.indent(2, [classmethods_content, methods_content].join('\n\n'));
109 | return Utils.render(
110 | '[ Class <% class_name %> extend <% parent_class_name %>\n\n<% content %>\n]',
111 | {class_name: this.name, parent_class_name: this.parent.name, content: content});
112 | };
113 |
114 |
115 | var Class = function Class(name, parent){
116 | var parent = parent || Object;
117 |
118 | var child = eval(named(name, function(){
119 | var this_class = arguments.callee;
120 | var obj;
121 | if(this instanceof this_class){
122 | if (!!this_class.__sign__){
123 | delete this_class.__sign__;
124 | return;
125 | } else {
126 | obj = this;
127 | }
128 | }
129 | else{
130 | this_class.__sign__ = true;
131 | obj = new this_class();
132 | }
133 | obj.__class__ = this_class;
134 | this_class.prototype['__constructor__'].apply(obj, arguments);
135 |
136 | return obj;
137 | }));
138 |
139 | if (!!parent['parent'])
140 | parent.__sign__ = true;
141 | child.prototype = new parent();
142 | child.parent = parent;
143 |
144 | // function
145 | child.method = method;
146 | child.classmethod = classmethod;
147 | child.extend = extend;
148 | child.alias = alias;
149 | child.upper = upper;
150 | child.name = name;
151 | child.inspect = inspect;
152 |
153 | child.method('constructor', function(){
154 | if (child.upper('constructor'))
155 | child.upper('constructor').apply(this, arguments);
156 | });
157 |
158 | // init
159 | return child;
160 | };
161 |
162 | return Class;
163 | });
164 |
--------------------------------------------------------------------------------
/src/Utils.js:
--------------------------------------------------------------------------------
1 | define(function(){
2 |
3 | var Utils = {};
4 |
5 | Utils.indent = (function(){
6 | var indentStr = function indentStr(n, s){
7 | var n = n || 0;
8 | var s = s || ' ';
9 | var str = '';
10 | for (var i=0; i').map(function(piece){
83 | var p = piece.split('<%');
84 | return (p[0] || '') + ((p[1] && hook(values[p[1].replace(/^\s*(\w+)\s*$/,'$1')])) || '');
85 | }).join('');
86 | };
87 |
88 | Utils.inspect = function inspect(obj, depth){
89 | var indent = Utils.indent;
90 | var inspect = Utils.inspect;
91 | var attrs = Utils.attrs;
92 |
93 | if (typeof depth !== 'number')
94 | var depth = 3;
95 |
96 | if ( obj && typeof obj.inspect === 'function'){
97 | return obj.inspect(depth);
98 | }
99 | var t = typeof obj;
100 | if (t === 'undefined' ){
101 | return 'undefined'
102 | }
103 | else if (t === 'boolean' || t === 'number'){
104 | return obj.toString();
105 | }
106 | else if (t === 'string'){
107 | return JSON.stringify(obj);
108 | }
109 | else if (t === 'function'){
110 | if (obj.name){
111 | return '[Function: ' + obj.name + ']';
112 | }
113 | else {
114 | return '[Function]';
115 | }
116 | }
117 | else if (t === 'object'){
118 | if (obj === null){
119 | return 'null'
120 | }
121 | else if (obj instanceof RegExp || obj instanceof Date){
122 | return obj.toString();
123 | }
124 | else if (obj instanceof Array){
125 | if (depth < 0){
126 | return '[Array]';
127 | }
128 | else if (obj.length <= 0){
129 | return '[]';
130 | }
131 | else {
132 | var content = obj.map(function(item){
133 | return inspect(item, depth-1);
134 | });
135 | var content_str = content.join(',\n');
136 | if (content_str.length < 80){
137 | content_str = content.join(', ');
138 | }
139 | return '[ ' + indent.skipFirstLine(2, content_str) +' ]';
140 | }
141 | }
142 | else{
143 | if (depth < 0){
144 | return '[Object]';
145 | }
146 | else {
147 | var keys = attrs(obj).self;
148 | if (keys.length <= 0){
149 | return '{}';
150 | }
151 | else {
152 | var content = keys.map(function(key){
153 | if (/[a-zA-Z_$][a-zA-Z-$0-9]*/.test(key)){
154 | var key_str = key;
155 | }
156 | else {
157 | var key_str = inspect(key);
158 | }
159 | return key_str + ': ' + inspect(obj[key], depth-1);
160 | });
161 | var content_str = content.join(',\n');
162 | if (content_str.length < 80){
163 | content_str = content.join(', ');
164 | }
165 | return '{ ' + indent.skipFirstLine(2, content_str) +' }';
166 | }
167 | }
168 | }
169 | }
170 | };
171 |
172 | Utils.color = (function(){
173 | var render = Utils.render;
174 | var colors = {
175 | 'bold' : [1, 22],
176 | 'italic' : [3, 23],
177 | 'underline' : [4, 24],
178 | 'inverse' : [7, 27],
179 | 'white' : [37, 39],
180 | 'grey' : [90, 39],
181 | 'black' : [30, 39],
182 | 'blue' : [34, 39],
183 | 'cyan' : [36, 39],
184 | 'green' : [32, 39],
185 | 'magenta' : [35, 39],
186 | 'red' : [31, 39],
187 | 'yellow' : [33, 39]
188 | };
189 | return function color(c, str){
190 | return render(
191 | '\u001b[<%left%>m<%str%>\u001b[<%right%>m',
192 | { left: colors[c][0], right: colors[c][1], str: str}
193 | )
194 | };
195 | })();
196 |
197 | Utils.surround = function surround(pair, str){
198 | var left = pair.substr(0, pair.length/2);
199 | var right = pair.substr(pair.length/2);
200 | return left + str + right;
201 | }
202 |
203 | Utils.merge = function merge(target, obj){
204 | var attrs = Utils.attrs;
205 | var result = {};
206 |
207 | var target_keys = attrs(target).self;
208 | var obj_keys = attrs(obj).self;
209 |
210 | target_keys.forEach(function(key){
211 | result[key] = target[key];
212 | });
213 | obj_keys.forEach(function(key){
214 | result[key] = obj[key];
215 | });
216 | return result;
217 | };
218 |
219 | Utils.kv = function(key, value){
220 | var obj = {};
221 | obj[key] = value;
222 | return obj
223 | }
224 |
225 | Utils.importScope = function importScope(name){
226 | return Utils.render(
227 | 'for (this.__inject_key__ in <%name%>){ eval("var "+this.__inject_key__+"="+"<%name%>"+"."+this.__inject_key__)}; delete this.__inject_key__;'
228 | ,{name: name}
229 | );
230 | };
231 |
232 | Utils.uniqueId = (function(){
233 | var count = 0;
234 | return function uniqueId(){
235 | return count++;
236 | }
237 | })();
238 |
239 | Utils.uniqueId.own = function(){
240 | return (function(){
241 | var count = 0;
242 | return function uniqueId(){
243 | return count++;
244 | }
245 | })()
246 | };
247 |
248 | Utils.equal = function equal(a, b){
249 | return (
250 | (typeof a === typeof b) && (
251 | (a === b) || (
252 | (typeof a.equal === 'function')
253 | && (!!(a.equal(b)))
254 | ) || (
255 | (a instanceof Array) && (b instanceof Array) && (Utils.equal.array(a, b))
256 | )
257 | )
258 | );
259 | };
260 |
261 | Utils.equal.array = function equalArray(a, b){
262 | return a.map(function(e, i){
263 | return [e, b[i]];
264 | }).reduce(function(last, item){
265 | return last && Utils.equal(item[0], item[1]);
266 | }, a.length === b.length);
267 | };
268 |
269 | return Utils;
270 | });
271 |
--------------------------------------------------------------------------------
/test_browser.html:
--------------------------------------------------------------------------------
1 | Test BlxScript in Browser
2 |
3 |
4 |
28 |
--------------------------------------------------------------------------------
/test_node.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | var Class = require('./dist/Class');
4 |
5 | var A = Class('A', Object)
6 | .method('constructor', function(){
7 | this.name = 'a';
8 | });
9 |
10 | var B = Class('B', A);
11 | B.method('run', function(){
12 | console.log('run');
13 | });
14 |
15 | var C = B.extend('C')
16 | .method('run', function(a){
17 | console.log('run a: ', a);
18 | })
19 | .method('run', function(a,b){
20 | console.log('run a, b: ', a, b);
21 | });
22 |
23 | var c = C();
24 | c.run();
25 | c.run(1);
26 | c.run(1,2);
27 |
--------------------------------------------------------------------------------