上篇文章中我们介绍了用工厂模式解决相似对象重复实例化产生大量代码的问题。这里接着上篇文章,先补充两个创建模式。
寄生构造函数
function Box(name,sex){ var obj=new Object(); obj.name=name; obj.sex=sex; obj.work=function(){ return this.name+' is working'; }; return obj; } var box1=new Box('Mr.R','man'); var box2=new Box('Mr.Q','man'); alert(box1 instanceof Box);//false alert(box2 instanceof Box);//false
工厂模式和这里的寄生构造函数不同在于,前者的方法名时createobject,创建对象时var box=createobject('Mr.R','man');后者就是把方法名首字母大写,实例化时用new,看起来像构造函数,实际上是工厂模式,它乔装打扮一番,但是我们还不能拆穿它,给它取名寄生构造函数。
稳妥构造函数
仅仅是函数名称首字母大写,其他和工厂模式完全一样。稳妥构造函数特点:构造函数里不使用this,外部实例化不用new。
不论是寄生构造函数还是稳妥构造函数,仍具备工厂模式弊端,存在对象无法识别问题。
上篇文章我们介绍了构造函数,它可以解决对象重复实例化的问题,又能解决对象之间识别问题。
当我们通过构造函数创建出它的多个对象实例,这些对象实例之间,有不同之处,也有共同点。不同对象之间的差别我们可以通过向构造函数传参来解决,而相同的部分我们可以放到原型里面。
也就是说,不共享的放到构造函数里,共享的放到原型里。这就是引出了组合构造函数+原型模式,这是最最基本的。
组合构造函数+原型模式
function Box(name,age){ this.name=name; this.age=age; } Box.prototype.run=function(){ return 123; };
如果原型中的属性和方法在构造函数外定义,那么只有对象实例调用原型中的属性方法时才会执行;而现在放到构造函数里面,每次创建对象实例(new Box())时,原型的属性和方法就会被执行。
动态原型模式
function Box(name,age){ this.name=name; this.age=age; if(typeof this.run!='function'){ Box.prototype.run=function(){ return 123; }; } }
解决了上述问题,如果原型中的方法已经执行过一次,就不用再执行一遍。
总结:这里接着上篇文章又介绍了几种创建模式,简单的提到了原型。对于寄生构造函数,这里我没说它的具体应用,但是它结合原型使用扩展内置对象方法很不错,读者可以试试,这也从侧面说明了原型的不一般。我们通过对象的prototype属性来封装一些公共的属性,方法。每个对象默认都有这一属性。其实prototype属性指向了一个prototype对象。prototype属性和构造函数中的age,name属性不一样的是,它更像是一个属性集合。我们用原型就是希望一些共享的东西被复用,被继承。因为每一个对象都有prototype属性,那么通过它,把公共的东西放到里面,任何一个对象都有被复用也有复用其他对象的可能性,并且这种复用很方便啊。所以感觉原型很强大啊。