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){
		// 当前的item
		var 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、链太深之后,会造成子类过度臃肿

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

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

时间: 2024-11-08 09:13:21

javascript继承学习(一)的相关文章

JavaScript继承学习笔记

JavaScript作为一个面向对象语言(JS是基于对象的),可以实现继承是必不可少的,但是由于本身并没有类的概念,所以不会像真正的面向对象编程语言通过类实现继承,但可以通过其他方法实现继承.(javascript中的继承是通过原型链来体现的http://www.cnblogs.com/amumustyle/p/5435653.html)实现继承的方法很多,下面就只是其中的几种. 一.原型链继承 1 function Person() { //被继承的函数叫做超类型(父类,基类) 2 this.

javascript 继承 学习总结

看了不少js继承的东西也该总结总结了.先说一下大概的理解,有不对的还望指正,也好更正一下三观.另外说明下,下面的例子并非原创基本就是改了个变量名啥的,有的甚至直接拿过来用的. js继承是用来干啥的: 首先说js没有真正的跟其他面向对象的语言一样概念的继承,js里边所说的继承是指模拟继承. 具体js继承是干啥呢,刚开始做前端的时候我是用来面试的(最早写些小效果的时候基本用不到,为啥要看呢,因为面试官很爱问这个问题啊),所以就看看大概的,面试时候能说个大概,在这个问题上算是面试党了.后来跟着慢慢的实

【转载】Javascript原型继承-学习笔记

阮一峰这篇文章写的很好 http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html 笔记如下: 一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(p

JavaScript强化教程——Cocos2d-JS中JavaScript继承

JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来的,在Cocos2d-JS的早期版本Cocos2d-HTML中几乎全部的API都是模拟Cocos2d-x API而设计的,Cocos2d-x本身是有C++编写的,其中的很多对象和函数比较复杂,JavaScript语言描述起来有些力不从心了.在开源社区中John Resiq在他的博客(http://e

Javascript MVC 学习笔记(一) 模型和数据

写在前面 最近在看<MVC的Javascript富应用开发>一书,本来是抱着一口气读完的想法去看的,结果才看了一点就傻眼了:太多不懂的地方了.只好看一点查一点,一点一点往下看吧,进度虽慢但也一定要坚持看完.本学习笔记是对书上所讲解内容的理解和记录. 笔记里的代码大多会按书上摘录下来,因为<MVC的Javascript富应用开发>是结合了JQuery库,所以对于JQuery中不太懂的知识点也会附在代码后面,也算是一些额外的收获. MVC概述 要学习MVC,首先得知道MVC是什么,MV

【读书笔记】javascript 继承

在JavaScript中继承不像C#那么直接,C#中子类继承父类之后马上获得了父类的属性和方法,但JavaScript需要分步进行. 让Brid 继承 Animal,并扩展自己fly的方法. function Animal(name) { this.name = name; this.type = "animal"; } Animal.prototype= { say:function() { alert("I'm a " + this.type + ",

Cocos2d-JS中JavaScript继承

JavaScript语言本身没有提供类,没有其它语言的类继承机制,它的继承是通过对象的原型实现的,但这不能满足Cocos2d-JS引擎的要求.由于Cocos2d-JS引擎是从Cocos2d-x演变而来的,在Cocos2d-JS的早期版本Cocos2d-HTML中几乎全部的API都是模拟Cocos2d-x API而设计的,Cocos2d-x本身是有C++编写的,其中的很多对象和函数比较复杂,JavaScript语言描述起来有些力不从心了.在开源社区中John Resiq在他的博客(http://e

Javascript继承机制的设计思想

转自:http://www.ruanyifeng.com/blog/2011/06/designing_ideas_of_inheritance_mechanism_in_javascript.html 我一直很难理解Javascript语言的继承机制. 它没有"子类"和"父类"的概念,也没有"类"(class)和"实例"(instance)的区分,全靠一种很奇特的"原型链"(prototype chain

JavaScript 基础学习1-day14

JavaScript 基础学习1 知识预览JavaScript概述二 JavaScript的基础三 JavaScript的对象BOM对象DOM对象实例练习js扩展 JavaScript概述 JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言) Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator