js 创建对象的多种方式与优缺点小结
早期创建方式
varobj=newObject() obj.name='xxx' obj.age=18 或使用对象字面量 varo1={ name:'xxx', say:()=>{} } varo2={ name:'xxx', say:()=>{} }
缺点:使用同一个接口创建很多对象,会产生大量重复代码
工厂模式
functionfactory(name,age){ varobj=newObject() obj.name=name obj.age=age returnobj } varo1=factory(1,11) varo2=factory(2,22)
优点:解决了创建多个相似对象代码重复问题
缺点:无法识别对象是什么类型
构造函数模式
ECMAScript中可以使用构造函数创建特定类型的对象,如Object,Array这种原生构造函数。此外,也可以创建自定义构造函数,从而定义自定义对象的属性和方法。
functionPerson(name,age){ this.name=name this.age=age this.sayName=function(){ console.log(this.name) } } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.sayName()//1 o2.sayName()//2
优点:构造函数模式创建的实例可以区分类型标识(instanceof判断)
缺点:每个方法都需要在实例上重新创建,如两个实例的sayName方法任务相同,但是实际创建了两个Function实例
构造函数模式优化
functionPerson(name,age){ this.name=name this.age=age } functionsayName(){ console.log(this.name) } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.sayName()//1 o2.sayName()//2
优点:多个实例共享在全局作用域中定义的函数,解决了两个函数做同一件事的问题
缺点:全局作用域定义的函数实际上只能被某个对象调用,全局作用域名不副实,而且如果对象需要定义很多方法,需要创建很多个全局函数,这让自定义的对象类型没有封装特性。
原型模式
我们创建的每个函数都有一个protoype属性,这个属性是一个指针,指向一个对象。这个对象的用途是包含了可以由特定类型的所有实例共享的属性和方法。即prototype就是由构造函数创建的那个对象实例的原型对象。
functionPerson(){} Person.prototype.name='123' Person.prototype.age=18 Person.prototype.sayName=function(){ console.log(this.name) } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.sayName()//123 o2.sayName()//123
优点:解决了实例共享属性或事件的问题
缺点:因为实例共享属性的原因,对于值为引用类型的属性来说,一个实例的修改会导致其他实例访问值更改。如:
functionPerson(){} Person.prototype.name='123' Person.prototype.age=18 Person.prototype.friends=['a','b'] Person.prototype.sayName=function(){ console.log(this.name) } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.friends.push('c') console.log(o2.friends)//['a','b','c']
构造函数和原型模式组合
functionPerson(name,age){ this.name=name this.age=age this.friends=['a'] } Person.prototype={ constructor:Person, sayName:function(){ console.log(this.name) } } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.sayName()//1 o2.sayName()//2
优点:每个实例有自己的属性,同时又共享着方法的引用,还支持传参数
动态原型模式
functionPerson(name,age){ this.name=name this.age=age this.friends=['a'] if(typeofthis.sayName!='function'){ Person.prototype.sayName=function(){ console.log(this.name) } } } varo1=newPerson(1,11) varo2=newPerson(2,22) o1.sayName()//1 o2.sayName()//2
优点:仅在方法不存在的时候创建一次,避免重复创建
寄生构造函数模式
functionSpecialArray(){ varo=newArray() //添加值 o.push.apply(o,arguments) //添加方法 o.toPipedString=function(){ returnthis.join('|') } returno } varo1=newSpecialArray(1,11) o1.toPipedString()//1|11
优点:在不更改原始构造函数的情况下为对象添加特殊方法
缺点:返回的对象与构造函数以及构造函数的原型没有任何关系,该方法与在构造函数外部创建的对象没有什么不同
稳妥构造函数模式
functionPerson(name){ varo=newObject() //添加方法 o.getName=function(){ returnname } returno } varo1=newPerson(1) o1.getName()//1
与寄生构造函数不同在于,不使用this,不使用new调用
优点:除了使用getName外没有任何方法能够访问name,在一些安全的环境使用
缺点:与工厂模式相似,无法识别对象所属类型
以上就是js创建对象的多种方式与优缺点小结的详细内容,更多关于js创建对象的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。