在游戏引擎中使用继承
(function(){
var initializing = false,
fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/;
this.Class = function(){};
Class.extend = function(prop) {
var _super = this.prototype;
initializing = true;
var prototype = new this();
initializing = false;
for (var name in prop) {
prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) {
return function() {
var tmp = this._super;
this._super = _super[name];
var ret = fn.apply(this, arguments);
this._super = tmp;
return ret;
};
})(name, prop[name]) : prop[name];
}
function Class() {
if (!initializing && this.init) {
this.init.apply(this, arguments);
}
}
Class.prototype = prototype;
Class.prototype.constructor = Class;
Class.extend = arguments.callee;
return Class;
};
})();
这段代码的主旨是允许使用extend方法从现有类中派生出新类,继承得来的对象可像父对象那样共享相同的实例方法,可以通过子方法this._super()调用父方法。这一特殊情况由代码中部的循环进行处理,该循环并非仅是一味的拷贝整个方法,它会检查父类的现有方法,然后创建一个包装器函数,在调用期间,该函数临时将this.super方法设置成父类的定义
for (var name in prop) { prototype[name] = typeof prop[name] == "function" && typeof _super[name] == "function" && fnTest.test(prop[name]) ? (function (name, fn) { return function() { var tmp = this._super; this._super = _super[name]; var ret = fn.apply(this, arguments); this._super = tmp; return ret; }; })
上述代码检查属性是否已存在于超类中,若是,则创建一个函数,在再次调用新方法之前,该函数会先对this._super执行一个临时赋值,若该方法不存在,代码仅对属性赋值,不会加入任何额外开销。
Class 代码还加入了一个构造函数,该函数自动调用对象的init()方法,还支持初始化函数的链式调用
function Class() { if (!initializing && this.init) this.init.apply(this, arguments); }
最后把extend方法添加到类中,这样类就可以进一步子类化:
Class.extend = arguments.callee;
调用arguments.calle时,会返回被调用的方法(在该例中是extend),然后把方赋给所返回的Class对象的属性extend,以此来支持进一步的子类化。
运用Class的功能
var Person = Class.extend({
init: function(){console.log('created person');},
speak: function(){console.log('person speaking');}
});
var p = new Person();
p.speak();
var Guy = Person.extend({
init: function(){this._super();console.log('created guy');},
speak: function(){this._super();console.log('i am a guy');}
});
var bob = new Guy();
bob.speak();
var Girl = Person.extend({
init: function(){console.log('created girl');},
speak: function(){console.log('i am a girl');}
});
var jill = new Girl();
jill.speak();
类功能使得以一种清晰的方式创建并扩展类成为可能,这些子类确保超类的方法能在适当的时候被调用。
bob instanceof Person //true bob instanceof Guy //true bob instanceof Girl //false jill instanceof Person //true jill instanceof Guy //false jill instanceof Girl //true
该功能也简化了必要时对于对象类型的使用,可以注意到,bob和jill都如预期般响应了instanceof运算符。