javascript继承学习(一)

网上的众多javascript继承方式,这里是不会详细讲解的,需要的,请自己度娘或谷爹。

之前做cocos2d-js的游戏,发现它有一个很有趣的继承方式。

形式如下:

var A = cc.Class.extend({// 一系列的函数等ctor: function(){// this._super指向了父亲的ctor方法,不明觉厉啊this._super();}});

于是研究了一下,主要有几点需要注意的:

1、function.toString会返回整个函数的定义字符串2、str.indexOf方法,有两个参数,第一个是字符串,第二个是起始检查的位置,它第一次匹配上,就结束了3、它的this._super方法,是通过匹配 或 闭包改写,弄出来的

于是,尝试了一下,自己去实现:

function Class(){};// compileSuper在某些特定情况下,才有用咯~,不过,它更节省内存空间,如果不需要调试,可以启用这种继承Class.compileSuper = function(fnStr, fnName){// 找出fn的参数var pstart = fnStr.indexOf("("), pend = fnStr.indexOf(")");var params = fnStr.slice(pstart + 1, pend);// 从fn主体开始寻找var str = fnStr.substring(fnStr.indexOf("{") + 1, fnStr.lastIndexOf("}"));// 替换掉this._super,为this.super[name]// cocos2d-js里,是通过for循环来实现的,但因为这里多记录了一个super字段,所以没有它的烦恼~var keyName = "this.super." + fnName;str = str.replace(/this._super/g, "this.super && " + keyName + " && " + keyName);// 返回新的函数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;// 下面这个for循环,如果再包装一下,就可以实现多参数形式了~,实验,不过多考虑for(var key in proto){// 当前的itemvar item = proto[key];// 如果父类和当前,都是函数,则有继承关系var isSuperFunc = "function" == typeof _super[key], isFunc = "function" == typeof item;if(isFunc && isSuperFunc){// 实现继承,包装一个super方法,,如果存在_super这样的字段,则编译var reg = /\b_super\b/, itemStr = item.toString();if(reg.test(itemStr)){// 有_super方法,则编译super方法// 但是一点都不好调试,可以考虑在其它模式下【如不想被别人调试的时候…】,使用这种编译// 这里主要做实验,就不一一操作了// fn[key] = Class.compileSuper(itemStr, key);// 放弃编译的方法,使用闭包fn[key] = (function(key, proto){return function(){var tmp = this._super;// 这一句依赖后面的 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;}};// 可以通过super寻找到父类fn.super = _super;myClass.extend = fn.extend = Class.extend;return myClass;};

因无法调试等原因,丢弃了匹配【重新编译字符串】的实现,使用了闭包。

但是闭包带来了额外的内存消耗,所以,如果真正上线,最好还是使用匹配的实现。

下面看两个例子:

var myFirst = Class.extend({constroctor: myFirst,ctor: function(name){// 因为父类Class,没有ctor方法,所以this._super(name);的调用,会报错// this._super(name);console.log(name);}});var mySecond = myFirst.extend({ctor: function(name, age){// 继承了myFirst,因为myFirst有ctor方法,所以,this._super(name)正常使用this._super(name);console.log(age);}});// 最终数据:var ss = new mySecond("da宗熊", 26);// 输出: da宗熊 26

代码看着挺优雅的,

但这种实现,也有一定的局限性:

1、约定了ctor为构造函数,new操作,实际调用了ctor的操作【可容忍】

2、继承没有筛选属性,会把父类的所有属性继承下来

3、链太深之后,会造成子类过度臃肿

个人觉得,较为简单的项目,是完全没必要使用的。

只有项目中,有强烈的上下级继承关系的时候,才是它发光发热的时候。

自己要先看得起自己,别人才会看得起你

javascript继承学习(一)

相关文章:

你感兴趣的文章:

标签云: