JavaScript深入系列第十四篇讲解对象的各种创建方式,以及优缺点。写在前面的文章中解释了创建对象的各种方式,以及它们的优缺点。但是注意:这篇文章更像是一个笔记,因为《JavaScript高级程序设计》写的太好了!1.工厂模式functioncreatePerson(name){varo=newObject();o.name=name;o.getName=function(){console.log(this.name);};returno;}varperson1=createPerson('kevin');缺点:无法识别对象,因为原型指向Object2。构造函数模式functionPerson(name){this.name=name;this.getName=function(){console.log(this.name);};}varperson1=newPerson('kevin');优点:可以将实例标识为特定类型缺点:每次创建实例,每个方法都必须创建一次2.1构造函数模式优化functionPerson(name){this.name=name;this.getName=getName;}functiongetName(){console.log(this.name);}varperson1=newPerson('kevin');优点:解决每个方法都要重新创建的问题缺点:这叫什么封装...3.原型模式functionPerson(name){}Person.prototype.name='keivn';Person.prototype.getName=function(){console.log(this.name);};varperson1=newPerson();优点:不会重新创建方法缺点:1.所有属性和方法都是共享的2.不能初始化参数3.1原型模式优化functionPerson(name){}Person.prototype={name:'kevin',getName:function(){console.log(this.name);}};varperson1=newPerson();优点:更好的封装缺点:重写原型,constructor属性丢失3.2原型模式优化functionPerson(name){}Person.prototype={constructor:Person,name:'kevin',getName:function(){console.log(this.name);}};varperson1=newPerson();优点:实例可以通过constructor属性找到构造函数缺点:原型模式应该有缺点还是有的4.组合方式构造器模式和原型模式结合起来}};varperson1=newPerson();优点:共享共享,private私有,使用最广泛的方法缺点:有些人就是想把它们都写在一起,也就是更好的封装4.1动态原型模式functionPerson(name){this.name=name;if(typeofthis.getName!="function"){Person.prototype.getName=function(){console.log(this.name);}}}varperson1=newPerson();注意:当使用动态原型模式时,原型不能被对象字面量覆盖。解释原因:}}}}varperson1=newPerson('kevin');varperson2=newPerson('daisy');//报错,没有这个方法person1.getName();//把上面的代码注释掉,这句话是可以执行的。person2.getName();为了解释这个问题,假设执行了varperson1=newPerson('kevin')。如果你对new和apply的底层执行过程不是很熟悉,可以阅读底部相关链接中的文章。我们回顾一下new的实现步骤:首先创建一个对象,然后将对象的原型指向Person.prototype,然后Person.apply(obj)返回这个对象。注意,此时回顾apply的实现步骤,会执行obj.Person方法。届时,if语句中的内容就会被执行。请注意,构造函数的原型属性指向实例的原型。使用字面量方法直接覆盖Person.prototype不会改变实例原型的值。Person1仍然指向之前的原型,而不是Person.prototype。之前的原型没有getName方法,所以报错!如果你只是想以文字的方式编写代码,你可以试试这个:functionPerson(name){this.name=name;if(typeofthis.getName!="function"){Person.prototype={constructor:Person,getName:function(){console.log(this.name);}}returnnewPerson(name);}}varperson1=newPerson('kevin');varperson2=newPerson('daisy');person1.getName();//kevinperson2.getName();//daisy5.1寄生构造函数模式functionPerson(name){varo=newObject();o.name=name;o.getName=function(){console.log(this.name);};returno;}varperson1=newPerson('kevin');console.log(person1instanceofPerson)//falseconsole.log(person1instanceofObject)//真正的寄生构造器模式,我个人觉得应该这样读:Parasitic-constructor-mode,也就是说,寄生在构造函数中的一个方法。也就是说,在构造函数的幌子下,可以看到创建的实例不能使用instanceof指向构造函数!这种方法可以在特殊情况下使用。例如,如果我们想创建一个带有附加方法的特殊数组,但不想直接修改Array构造函数,我们可以这样写:functionSpecialArray(){varvalues=newArray();for(vari=0,len=arguments.length;i
