JavaScript語言自己沒有提供類,沒有其它語言的類繼承機制,它的繼承是經過對象的原型實現的,但這不能知足Cocos2d-JS引擎的要求。因爲Cocos2d-JS引擎是從Cocos2d-x演變而來的,在Cocos2d-JS的早期版本Cocos2d-HTML中幾乎所有的API都是模擬Cocos2d-x API而設計的,Cocos2d-x自己是有C++編寫的,其中的不少對象和函數比較複雜,JavaScript語言描述起來有些力不從心了。
在開源社區中John Resiq在他的博客(http://ejohn.org/blog/simple-javascript-inheritance/)中提供了一種簡單JavaScript繼承(Simple JavaScript Inheritance)方法。
John Resiq的簡單JavaScript繼承方法靈感來源於原型繼承機制,它具備與Java等面向對象同樣的類概念,而且他設計了全部類的根類Class,它的代碼以下:
javascript
[html] view plaincopyhtml
/* Simple JavaScript Inheritance java
* By John Resig http://ejohn.org/ 微信
* MIT Licensed. app
*/ 函數
// Inspired by base2 and Prototype 學習
(function(){ 網站
var initializing = false, fnTest = /xyz/.test(function(){xyz;}) ? /\b_super\b/ : /.*/; this
// The base Class implementation (does nothing) spa
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;
};
})();
與Java中的Object同樣全部類都直接或間接繼承於Class,下面是繼承Class實例:
[html] view plaincopy
var Person = Class.extend({ ①
init: function (isDancing) { ②
this.dancing = isDancing;
},
dance: function () { ③
return this.dancing;
}
});
var Ninja = Person.extend({ ④
init: function () { ⑤
this._super(false); ⑥
},
dance: function () { ⑦
// Call the inherited version of dance()
return this._super(); ⑧
},
swingSword: function () { ⑨
return true;
}
});
var p = new Person(true); ⑩
console.log(p.dance());// true ⑪
var n = new Ninja(); ⑫
console.log(n.dance()); // false ⑬
console.log(n.swingSword()); // true
若是你對於Java語言的面向對象很熟悉的話,應該很容易看懂。其中第①行代碼是聲明Person類,它繼承自Class,Class.extend()表示繼承自Class。第②行代碼的定義構造函數init,它的做用是初始化屬性。第③行代碼是定義普通函數dance(),它能夠返回屬性dancing。
第④行代碼是聲明Ninja類繼承自Person類,第⑤行代碼的定義構造函數init,在該函數中this._super(false)語句是調用父類構造函數初始化父類中的屬性,見代碼第⑥行所示。第⑦行代碼是重寫dance()函數,它會覆蓋父類的dance()函數。第⑧行代碼是this._super()是調用父類的dance()函數。第⑨行代碼是子類Ninja新添加的函數swingSword()。
第⑩行代碼經過Person類建立p對象,給構造函數的參數是true。第⑪行代碼是打印日誌p對象dance屬性,結果爲true。
第⑫行代碼經過Ninja類建立n對象,構造函數的參數爲空,默認初始化採用false初始化父類中的dance屬性。所以在代碼第⑬行打印爲false。
這種簡單JavaScript繼承方法事實上實現了通常意義上的面向對象概念的繼承和多態機制。這種簡單JavaScript繼承方法是Cocos2d-JS繼承機制的核心,Cocos2d-JS稍微作了修改,熟悉簡單JavaScript繼承的用法對於理解和學習Cocos2d-JS很是的重要。
更多內容請關注最新Cocos圖書《Cocos2d-x實戰:JS卷——Cocos2d-JS開發》
本書交流討論網站:http://www.cocoagame.net
歡迎加入Cocos2d-x技術討論羣:257760386
更多精彩視頻課程請關注智捷課堂Cocos課程:http://v.51work6.com
智捷課堂現推出Cocos會員,敬請關注:http://v.51work6.com/courseInfoRedirect.do?action=netDetialInfo&courseId=844465&categoryId=0
《Cocos2d-x實戰 JS卷》現已上線,各大商店均已開售:
京東:http://item.jd.com/11659698.html
歡迎關注智捷iOS課堂微信公共平臺,瞭解最新技術文章、圖書、教程信息