在讨论如何解决上次的问题前,我们先来区分一下在js里,什么是对象什么是类。
类指的是对一群具有相同特征的对象的集合的描述,而对象指的是真实存在的对象个体。打个简单的例子:类好比是一个模子,对象就是模子弄出来的东西。模子有一个,但是可以弄出来很多个东西。之所以说这个,是为了引出我下面将要讲的部分,原型模式(prototype)。
上一篇文章在讲到构造函数模式的时候,如果实例化多个对象的时候,其实是会不断的占内存,为什么呢?如果我们在构造函数内添加一个不变的属性或者不变的方法,如:
function hc(name,age) { this.name=name; this.age=age; this.showc=function () { alert(this.name+" "+this.age) } this.high="180"; this.say=function () { alert("hello") } }
var hc1=new hc("h1h2",21); var hc2=new hc("h2h2",21); alert(hc1.high); hc1.say(); alert(hc2.high); hc2.say();表面上看好像没什么,但是他们生成的内容却是一样的,如果每次生成的都是这种同样的内容,每次就会占着一部分内存。所以这个时候如果我们要把他在内存中只生成一次,每次实例化对象的时候都能指向那个地址来减少内存的话,我们就要用到原型模式。
在js里面,每个构造函数都有一个prototype属性,用以指向一个对象。这个对象的所有属性和方法都会被它的构造函数的实例所继承。也就是说,只要我们把构造函数里相同的属性和方法放入prototype中,那么每次引用它的时候都指向一个内存地址,从而不用占用多余的内存。具体如何实现请看下面的例子:
function hc(name,age) { this.name=name; this.age=age; this.showc=function () { alert(this.name+" "+this.age) } } hc.prototype.high="180"; hc.prototype.say=function () { alert("hello"); }如果我们这个时候来比较一下两个实例对象所引用的相同属性的内存地址的话,可以发现是一样的:
alert(hc1.high==hc2.high) //true这样子减少了内存的占用,提高了运行的效率。
同理,如果在一个Array类中有多个实例,实例arr1有一个add方法来求总和,而其他的没有,如果我们想要其他的都有这个方法的话可以这样:
Array.prototype.add=function () { //要实现的代码... }
除了上面的原型模式外,还有一种模式叫混合模式。所谓混合模式,就是混合的构造函数/原型模式,他的原则是构造函数加属性,原型模式加方法。其实上面原型模式的例子就是混合模式的例子。只不过在真正的原型模式中,没有this和参数,所以传的值都是比较死的,一般来说很少单纯用原型模式,因为不方便,更多的是用混合模式来进行js的面向对象的编程。
注意,构造函数的函数名要首字母大写,这个是一个规范。