最近看了Quintus引擎,感觉他的JS 架构做的不错,所以就自己模拟了一套。
其实,效果的话,没有效果,比较枯燥,但是他的JS de 格式写的着实不错,继承,重写一一用到,接下来看代码:
示例1:
创建index.html文件
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<title>模拟Quintus引擎 de JS</title>
<style>
body {
padding: 0;
margin: 0
}
</style>
</head>
<body>
这里是模拟JS
</body>
<script src="../../build/jquery.min.js"></script>
<script src="../../build/underscore-min.js"></script>
<script src="js/main.js"></script>
<script src="js/main-showBy.js"></script>
<script>
var By = mainBy().include("ShowBy");
By.input.csdn("bai");
</script>
</html>
PS:main.js、main-showBy.js的文件分别是我自己创建的。
不懂underscore-min.js的请移步:这里写链接内容
main.js文件
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function() {
var initializing = false,
fnTest = /xyz/.test(function() {
xyz;
}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function() {};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" &&
fnTest.test(prop[name]) ?
(function(name, fn) {
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.init)
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
var mainBy = function(opts) {
var By = {};
if (opts) {
_(By.options).extend(opts);
}
By._aaa = function() {
console.log("AAA");
}
By._bbb = function() {
console.log("BBB");
}
By._ccc = function() {
console.log("CCC");
}
By.extend = function(obj) {
alert(obj);
_(By).extend(obj);
return By;
};
// Syntax for including other modules into By
By.include = function(mod) {
_.each(By._normalizeArg(mod), function(m) {
m = mainBy[m] || m;
m(By);
});
return By;
};
By._normalizeArg = function(arg) {
if (_.isString(arg)) {
arg = arg.replace(/\s+/g, '').split(",");
}
if (!_.isArray(arg)) {
arg = [arg];
}
return arg;
};
By.Evented = Class.extend({
bind: function(event, target, callback) {
// Handle the case where there is no target provided
if (!callback) {
callback = target;
target = null;
}
// Handle case for callback that is a string
if (_.isString(callback)) {
callback = target[callback];
}
this.listeners = this.listeners || {};
this.listeners[event] = this.listeners[event] || [];
this.listeners[event].push([target || this, callback]);
if (target) {
if (!target.binds) {
target.binds = [];
}
target.binds.push([this, event, callback]);
}
},
trigger: function(event, data) {
if (this.listeners && this.listeners[event]) {
for (var i = 0, len = this.listeners[event].length; i < len; i++) {
var listener = this.listeners[event][i];
listener[1].call(listener[0], data);
}
}
},
unbind: function(event, target, callback) {
if (!target) {
if (this.listeners[event]) {
delete this.listeners[event];
}
} else {
var l = this.listeners && this.listeners[event];
if (l) {
for (var i = l.length - 1; i >= 0; i--) {
if (l[i][0] == target) {
if (!callback || callback == l[i][1]) {
this.listeners[event].splice(i, 1);
}
}
}
}
}
},
debind: function() {
if (this.binds) {
for (var i = 0, len = this.binds.length; i < len; i++) {
var boundEvent = this.binds[i],
source = boundEvent[0],
event = boundEvent[1];
source.unbind(event, this);
}
}
}
});
return By;
}
main-showBy.js文件
mainBy.ShowBy = function(By) {
By.InputSystem = By.Evented.extend({
init:function(){
console.log("进入ShowBy的初始化方法");
},
csdn: function(name) {
console.log("进入ShowBy的By.InputSystem方法---" + name);
},
bindKey: function(key, name) {
By.input.keys[KEY_NAMES[key] || key] = name;
}
});
By.input = new By.InputSystem();
console.log("bai123__" + By);
By.addClassBai = function(){
console.log("进入ShowBy的addClassBai方法");
}
return By;
}
示例2:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta content="width=device-width,initial-scale=1.0,maximum-scale=1.0,user-scalable=no" name="viewport">
<title>模拟JS</title>
<style>
body {
padding: 0;
margin: 0
}
</style>
</head>
<body>
这里是模拟JS
</body>
<script src="../../build/jquery.min.js"></script>
<script src="../../build/underscore-min.js"></script>
<script src="js/main.js"></script>
<script src="js/main-showBy.js"></script>
<script src="js/main-Sprite.js"></script>
<script>
var By = mainBy().include("ShowBy,Sprite");
By.input.csdn("baiyu");
By.Paddle = By.Sprite.extend({
init: function() {
console.log("进入Q.Paddle 的初始化方法");
},
setUp:function(){
console.log("进入Q.Paddle 的setUp()方法");
}
});
By.init();
</script>
</html>
引入三个文件
<script src="js/main.js"></script>
<script src="js/main-showBy.js"></script>
<script src="js/main-Sprite.js"></script>
(1)main.js文件
/* Simple JavaScript Inheritance
* By John Resig http://ejohn.org/
* MIT Licensed.
*/
// Inspired by base2 and Prototype
(function() {
var initializing = false,
fnTest = /xyz/.test(function() {
xyz;
}) ? /\b_super\b/ : /.*/;
// The base Class implementation (does nothing)
this.Class = function() {};
// Create a new Class that inherits from this class
Class.extend = function(prop) {
var _super = this.prototype;
// Instantiate a base class (but only create the instance,
// don't run the init constructor)
initializing = true;
var prototype = new this();
initializing = false;
// Copy the properties over onto the new prototype
for (var name in prop) {
// Check if we're overwriting an existing function
prototype[name] = typeof prop[name] == "function" &&
typeof _super[name] == "function" &&
fnTest.test(prop[name]) ?
(function(name, fn) {
return function() {
var tmp = this._super;
// Add a new ._super() method that is the same method
// but on the super-class
this._super = _super[name];
// The method only need to be bound temporarily, so we
// remove it when we're done executing
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) :
prop[name];
}
// The dummy class constructor
function Class() {
// All construction is actually done in the init method
if (!initializing && this.init)
this.init.apply(this, arguments);
}
// Populate our constructed prototype object
Class.prototype = prototype;
// Enforce the constructor to be what we expect
Class.prototype.constructor = Class;
// And make this class extendable
Class.extend = arguments.callee;
return Class;
};
})();
var mainBy = function(opts) {
var By = {};
if (opts) {
_(By.options).extend(opts);
}
By._aaa = function() {
console.log("AAA");
}
By._bbb = function() {
console.log("BBB");
}
By._ccc = function() {
console.log("CCC");
}
By.extend = function(obj) {
console.log("进入父类的extend继承方法");
_(By).extend(obj);
return By;
};
// Syntax for including other modules into By
By.include = function(mod) {
_.each(By._normalizeArg(mod), function(m) {
m = mainBy[m] || m;
m(By);
});
return By;
};
By._normalizeArg = function(arg) {
if (_.isString(arg)) {
arg = arg.replace(/\s+/g, '').split(",");
}
if (!_.isArray(arg)) {
arg = [arg];
}
return arg;
};
By.Evented = Class.extend({
bind: function(event, target, callback) {
// Handle the case where there is no target provided
if (!callback) {
callback = target;
target = null;
}
// Handle case for callback that is a string
if (_.isString(callback)) {
callback = target[callback];
}
this.listeners = this.listeners || {};
this.listeners[event] = this.listeners[event] || [];
this.listeners[event].push([target || this, callback]);
if (target) {
if (!target.binds) {
target.binds = [];
}
target.binds.push([this, event, callback]);
}
},
trigger: function(event, data) {
if (this.listeners && this.listeners[event]) {
for (var i = 0, len = this.listeners[event].length; i < len; i++) {
var listener = this.listeners[event][i];
listener[1].call(listener[0], data);
}
}
},
unbind: function(event, target, callback) {
if (!target) {
if (this.listeners[event]) {
delete this.listeners[event];
}
} else {
var l = this.listeners && this.listeners[event];
if (l) {
for (var i = l.length - 1; i >= 0; i--) {
if (l[i][0] == target) {
if (!callback || callback == l[i][1]) {
this.listeners[event].splice(i, 1);
}
}
}
}
}
},
debind: function() {
if (this.binds) {
for (var i = 0, len = this.binds.length; i < len; i++) {
var boundEvent = this.binds[i],
source = boundEvent[0],
event = boundEvent[1];
source.unbind(event, this);
}
}
}
});
return By;
}
(2)main-showBy.js文件
mainBy.ShowBy = function(By) {
By.InputSystem = By.Evented.extend({
init:function(){
console.log("进入ShowBy的初始化方法");
},
csdn: function(name) {
console.log("进入ShowBy的By.InputSystem方法---" + name);
},
bindKey: function(key, name) {
By.input.keys[KEY_NAMES[key] || key] = name;
}
});
By.input = new By.InputSystem();
console.log("baiyu123__" + By);
By.addClassBai = function(){
console.log("进入ShowBy的addClassBai方法");
}
return By;
}
(3)main-Sprite.js文件
mainBy.Sprite = function(By) {
By.SpriteSheet = Class.extend({
init: function() {
console.log("进入Sprite的 By.SpriteSheet 初始化方法");
},
draw: function() {
console.log("进入Sprite的draw()方法");
}
});
By.Sprite = By.extend({
init: function() {
console.log("进入Sprite的 By.Sprite 初始化方法");
}
});
//切勿混乱,一个是大写,一个是小写
By.sprite = function(name,scenceObj){
console.log("这里是mainBy.Sprite的带有参数的方法!" + name);
}
return By;
}