前次讲了一下在行使JavaScript举办面向工具编程中,回收结构法来实现类担任的一些优弱点。下面我们接着把'原型担任法'的也有弱点也讲一讲,但愿各人能起劲提意见并切磋个中的一些题目。
原型(prototype)是JavaScript实现面向工具编程的一个基本,但它并不是独一的结构类的要领,我们完全可以不行使prototype而实现类的编写(把属性和要领的附加全都写在结构函数内里就行了)。不外原型除了可觉得Object的子类添加新的属性和要领外,它还可觉得剧本情形中的内部工具继承添加原型属性和要领,好比我们最常用的给内部工具String添加一个Trim要领来删除字符串两头的空格,代码为:
这样我们就可以在任何的String实例中行使Trim要领了,用惯了这种原型体系,有的时辰反而还认为传统OOP没有它爽,kaka。言归正传,继承讲我们的原型担任法。
原型担任法的道理:
原型担任法的要害代码是其结构函数function ArrayList02()下的第一句:
Ae… 把prototype都包围成基类的一个实例了,子类还怎么行使prototype呢?这里不要着急,横竖JavaScript的工具实例都是可以动态增删属性和要领的,基类实例作为prototype不就正好便是extends了CollectionBase吗?之后再行使XXX.prototype.xxx = function(),可以继承得到新增了属性和要领的工具。留意ArrayList02.prototype是在ArrayList02的结构函数外被初始化为基类的实例的。
再来看第二句,为什么要把ArrayList02赋值给新prototype的constructor呢?假如不做这个赋值,当我们从ArrayList02的实例中,通过???.prototype.constructor去却其结构函数,将会得到CollectionBase。这不是我们的本意,并且这是行使instanceof要害之较量工具实例和工具也会堕落。
原型担任法的缺陷:
原型担任法有两个缺陷,第一个是因为类的原型(prototype)现实上是一个Object的实例,它不能再次被实例化(它的初始化在剧本装载时已经执行完毕)。这么意思呢?我们知道在新建工具实例时,我们行使语句new ArrayList02(),这时我们可以看做JavaScript剧本引擎把prototype的一个浅拷贝作为this返回给类的实例(这里着实没有产生拷贝,只是操作浅拷贝这个观念来辅佐领略),假如类没有附加任何原型属性和原型要领,那么就便是返回了一个new Object()实例。题目就出在这里了,因为new对prototype执行的是浅拷贝,假如prototype的原型属性里有工具范例的属性,那么就会造成共享工具实例的题目(相同于在传统OOP的类界说中行使了static修饰符来修饰了属性)。这个缺陷下面会有示例演示,停止的步伐就是不要在基类中界说工具范例的属性,好比: Array、Object和Date等。 第二个缺陷和前次讲的"结构担任法"的缺陷差不多,也是关于子类界说是语句次序的。就是说代码:ArrayList02.prototype = new CollectionBase();必需在全部prototype界说之前执行,很简朴,假如在原型属性和要领都导入完成后,再执行这个语句,就定于把之前的导入全都包围掉了:(。办理步伐就噬洗我给文章(1)中的谁人次序来写,忧郁吧?kaka
原型担任法的示例:
示例运行功效为:
本相担任法: [class ArrayList02]: 2: a,b [class ArrayList02]: 3: a,b,c,a,b
发明题目了吧?实例arrayList22的foo()居然输出了a,b,c,a,b@_@... 这就是前面说的prototype工具浅拷贝带来的题目。不外为什么arrayList22中的荟萃计数器却如故是3呢?这是由于this.m_Count是整数范例,这种范例又叫值范例(和C#里的值范例、工具范例观念一样的)。值范例不存在浅拷贝和深拷贝的题目,可以当作都是深拷贝。
小结:JavaScript的原型担任法,固然有prototype浅拷贝那么严峻的bug,不外它却是行使较量多的担任方法。由于我们很少在基类里界说属性,更别说工具范例的属性了,以是激发这个错误的也许性不是很大,只是它是个隐藏的隐患:(。至于第二个缺陷,也是一个隐藏bug,只要本身界说类的时辰能较量苏醒就不会失足误。'重载'也较量简朴,假如在ArrayList02.prototype = new CollectionBase();后有重名的属性或要教育入,自动包围基类中的属性或要领就像当于重载了。
应用场景:基类没有属性,至少是要没有工具范例的属性。这种担任的利益是保持了子类结构函数的完备,可以不在内里添加任何和担任有相关的代码,全部担任和重载操纵都由对原型(prototype)的操纵来完成。
to be continued ...
(责任编辑:admin) |