Javascript inheritance (1)
Many javascript inheritance methods on the Internet will not be described in detail here. If you need them, please do your best.
The previous cocos2d-js game found it had a very interesting inheritance method.
The format is as follows:
Var A = cc. class. extend ({// a series of functions, etc. ctor: function () {// this. _ super points to the father's ctor method. It's hard to find this. _ super ();}});
As a result, I have studied the following points:
1. function. toString returns the definition string of the entire function.
2. the str. indexOf method has two parameters: the first is the string, and the second is the position of the Start Check. It ends after the first match.
3. Its this. _ super method is rewritten by matching or closure.
So I tried to implement it myself:
Function Class () {}; // compileSuper is useful in certain situations ~, However, it saves more memory space. If debugging is not required, you can enable this inheritance Class. compileSuper = function (fnStr, fnName) {// find the fn parameter var pstart = fnStr. indexOf ("("), pend = fnStr. indexOf (")"); var params = fnStr. slice (pstart + 1, pend); // search for var str = fnStr from the fn subject. substring (fnStr. indexOf ("{") + 1, fnStr. lastIndexOf ("}"); // replace this. _ super, this. super [name] // In the cocos2d-js, it is implemented through the for loop, but because there is a super field recorded here, so there is no worries about it ~ Var keyName = "this. super. "+ fnName; str = str. replace (/this. _ super/g, "this. super & "+ keyName +" & "+ keyName); // return the new Function return new Function (params, str) ;}; Class. extend = function (proto) {var _ super = this. prototype; function myClass () {this. ctor & this. ctor. apply (this, arguments) ;}; var fn = myClass. prototype; // The for loop below. If you wrap it again, you can implement the multi-parameter form ~, Experiment, but consider for (var key in proto) {// The current itemvar item = proto [key]; // if the parent class and the current class are both functions, there is an inheritance relationship var isSuperFunc = "function" = typeof _ super [key], isFunc = "function" = typeof item; if (isFunc & isSuperFunc) {// implement inheritance. Wrap a super method. If a field such as _ super exists, compile var reg =/\ B _super \ B/, itemStr = item. toString (); if (reg. test (itemStr) {// If the _ super method exists, compile the super method // but it is not easy to debug at all, you can consider other modes, such as when you do not want to be debugged by others... ], use this kind of compilation // here for the main experiment, do not operate one by one // fn [key] = Class. compileSuper (itemStr, key); // discard the compilation method and use the closure fn [key] = (function (key, proto) {return function () {var tmp = this. _ super; // This sentence depends on the fn. super = _ super; this. _ super = this. super [key]; var res = item. apply (this, arguments); this. _ super = tmp; return res ;}}) (key, item) ;}else {fn [key] = item ;}} else {fn [key] = item ;}}; // you can find the parent class fn through super. super = _ super; myClass. extend = fn. extend = Class. extend; return myClass ;};
The implementation of matching the [re-compilation string] is discarded due to debugging failure and other reasons, and the closure is used.
However, the closure causes extra memory consumption. Therefore, if it is actually online, it is best to use the matching implementation.
The following are two examples:
Var myFirst = Class. extend ({constroctor: myFirst, ctor: function (name) {// this. _ super (name); will return an error // this. _ super (name); console. log (name) ;}}); var mySecond = myFirst. extend ({ctor: function (name, age) {// inherits myFirst, because myFirst has a ctor method, so, this. _ super (name) is used normally this. _ super (name); console. log (age) ;}}); // final data: var ss = new mySecond ("da Zong Xiong", 26); // output: da Zong Xiong 26
The code looks very elegant,
However, this implementation also has some limitations:
1. It is agreed that the ctor is a constructor, and the new operation actually calls the ctor operation [tolerable]
2. If no filtering attribute is inherited, all attributes of the parent class will be inherited.
3. When the chain is too deep, the subclass will be overly bloated.
I personally think that simple projects are completely unnecessary.
Only when there is a strong parent-child inheritance relationship in the project is the time when it shines.