JavaScript创建对象的方式有很多,通过Object构造函数或对象字面量的方式也可以创建单个对象,显然这两种方式会产生大量的重复代码,并不适合量产。接下来介绍七种非常经典的创建对象的方式,他们也各有优缺点。

工厂模式
function createPerson(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = createPerson('Jiang', 'student')
var person2 = createPerson('X', 'Doctor')
可以无数次调用这个工厂函数,每次都会返回一个包含两个属性和一个方法的对象
工厂模式虽然解决了创建多个相似对象的问题,但是没有解决对象识别问题,即不能知道一个对象的类型
构造函数模式
function Person(name, job) {
this.name = name
this.job = job
this.sayName = function() {
console.log(this.name)
}
}
var person1 = new Person('Jiang', 'student')
var person2 = new Person('X', 'Doctor')
没有显示的创建对象,使用new来调用这个构造函数,使用new后会自动执行如下操作
创建一个新对象
这个新对象会被执行[[prototype]]链接
这个新对象会绑定到函数调用的this
返回这个对象
使用这个方式创建对象可以检测对象类型
person1 instanceof Object // true person1 instanceof Person //true
但是使用构造函数创建对象,每个方法都要在每个实例上重新创建一次
原型模式
function Person() {
}
Person.prototype.name = 'Jiang'
Person.prototype.job = 'student'
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person()
将信息直接添加到原型对象上。使用原型的好处是可以让所有的实例对象共享它所包含的属性和方法,不必在构造函数中定义对象实例信息。
原型是一个非常重要的概念,在一篇文章看懂proto和prototype的关系及区别中讲的非常详细
更简单的写法
function Person() {
}
Person.prototype = {
name: 'jiang',
job: 'student',
sayName: function() {
console.log(this.name)
}
}
var person1 = new Person()
将Person.prototype设置为等于一个以对象字面量形式创建的对象,但是会导致.constructor不在指向Person了。
使用这种方式,完全重写了默认的Person.prototype对象,因此 .constructor也不会存在这里
Person.prototype.constructor === Person // false
如果需要这个属性的话,可以手动添加
function Person() {
}
Person.prototype = {
constructor:Person
name: 'jiang',
job: 'student',
sayName: function() {
console.log(this.name)
}
}
不过这种方式还是不够好,应为constructor属性默认是不可枚举的,这样直接设置,它将是可枚举的。所以可以时候,Object.defineProperty方法
Object.defineProperty(Person.prototype, 'constructor', {
enumerable: false,
value: Person
})
缺点
使用原型,所有的属性都将被共享,这是个很大的优点,同样会带来一些缺点
原型中所有属性实例是被很多实例共享的,这种共享对于函数非常合适。对于那些包含基本值的属性也勉强可以,毕竟实例属性可以屏蔽原型属性。但是引用类型值,就会出现问题了
function Person() {
}
Person.prototype = {
name: 'jiang',
friends: ['Shelby', 'Court']
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) //["Shelby", "Court", "Van"]
console.log(person1.friends === person2.friends) // true
friends存在与原型中,实例person1和person2指向同一个原型,person1修改了引用的数组,也会反应到实例person2中
组合使用构造函数模式和原型模式
这是使用最为广泛、认同度最高的一种创建自定义类型的方法。它可以解决上面那些模式的缺点
使用此模式可以让每个实例都会有自己的一份实例属性副本,但同时又共享着对方法的引用
这样的话,即使实例属性修改引用类型的值,也不会影响其他实例的属性值了
function Person(name) {
this.name = name
this.friends = ['Shelby', 'Court']
}
Person.prototype.sayName = function() {
console.log(this.name)
}
var person1 = new Person()
var person2 = new Person()
person1.friends.push('Van')
console.log(person1.friends) //["Shelby", "Court", "Van"]
console.log(person2.friends) // ["Shelby", "Court"]
console.log(person1.friends === person2.friends) //false
动态原型模式
动态原型模式将所有信息都封装在了构造函数中,初始化的时候,通过检测某个应该存在的方法时候有效,来决定是否需要初始化原型
function Person(name, job) {
// 属性
this.name = name
this.job = job
// 方法
if(typeof this.sayName !== 'function') {
Person.prototype.sayName = function() {
console.log(this.name)
}
}
}
var person1 = new Person('Jiang', 'Student')
person1.sayName()
只有在sayName方法不存在的时候,才会将它添加到原型中。这段代码只会初次调用构造函数的时候才会执行。
此后原型已经完成初始化,不需要在做什么修改了
这里对原型所做的修改,能够立即在所有实例中得到反映
其次,if语句检查的可以是初始化之后应该存在的任何属性或方法,所以不必用一大堆的if语句检查每一个属性和方法,只要检查一个就行
寄生构造函数模式
这种模式的基本思想就是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新建的对象
function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(this.name)
}
return o
}
var person1 = new Person('Jiang', 'student')
person1.sayName()
这个模式,除了使用new操作符并把使用的包装函数叫做构造函数之外,和工厂模式几乎一样
构造函数如果不返回对象,默认也会返回一个新的对象,通过在构造函数的末尾添加一个return语句,可以重写调用构造函数时返回的值
稳妥构造函数模式
首先明白稳妥对象指的是没有公共属性,而且其方法也不引用this。
稳妥对象最适合在一些安全环境中(这些环境会禁止使用this和new),或防止数据被其他应用程序改动时使用
稳妥构造函数模式和寄生模式类似,有两点不同:一是创建对象的实例方法不引用this,而是不使用new操作符调用构造函数
function Person(name, job) {
var o = new Object()
o.name = name
o.job = job
o.sayName = function() {
console.log(name)
}
return o
}
var person1 = Person('Jiang', 'student')
person1.sayName()
和寄生构造函数模式一样,这样创建出来的对象与构造函数之间没有什么关系,instanceof操作符对他们没有意义
以上所述是小编给大家介绍的JavaScript创建对象的七种方式,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对网站的支持!
# js创建对象的几种方式
# js创建对象的方式
# js对象创建方式
# js 创建对象的多种方式与优缺点小结
# 详解js创建对象的几种方式和对象方法
# javascript面向对象创建对象的方式小结
# JS中的函数与对象的创建方式
# JavaScript创建对象方式总结【工厂模式、构造函数模式、原型模式等】
# JavaScript创建对象的常用方式总结
# JavaScript实现创建自定义对象的常用方式总结
# JavaScript创建对象的七种方式全面总结
# 基于JS对象创建常用方式及原理分析
# JS创建对象的四种方式
# 也会
# 才会
# 小编
# 七种
# 自己的
# 是一个
# 这是
# 就会
# 也不
# 会有
# 都要
# 多个
# 在此
# 有很多
# 一是
# 做什么
# 要在
# 没有什么
# 这段
# 就行
相关文章:
C++ static_cast和dynamic_cast区别_C++静态转换与动态类型安全转换
定制建站流程步骤详解:一站式方案设计与开发指南
Java解压缩zip - 解压缩多个文件或文件夹实例
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
如何通过云梦建站系统实现SEO快速优化?
如何高效完成独享虚拟主机建站?
成都网站制作公司哪家好,四川省职工服务网是做什么用?
微信推文制作网站有哪些,怎么做微信推文,急?
如何快速搭建高效WAP手机网站?
如何确保西部建站助手FTP传输的安全性?
实现虚拟支付需哪些建站技术支撑?
昆明高端网站制作公司,昆明公租房申请网上登录入口?
如何快速搭建响应式可视化网站?
哪家制作企业网站好,开办像阿里巴巴那样的网络公司和网站要怎么做?
创业网站制作流程,创业网站可靠吗?
建站之家VIP精选网站模板与SEO优化教程整合指南
内部网站制作流程,如何建立公司内部网站?
如何用手机制作网站和网页,手机移动端的网站能制作成中英双语的吗?
青岛网站建设如何选择本地服务器?
建站之星2.7模板:企业网站建设与h5定制设计专题
电商网站制作公司有哪些,1688网是什么意思?
企业宣传片制作网站有哪些,传媒公司怎么找企业宣传片项目?
如何快速打造个性化非模板自助建站?
如何自定义建站之星模板颜色并下载新样式?
如何在IIS中配置站点IP、端口及主机头?
建站之星备案是否影响网站上线时间?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
制作证书网站有哪些,全国城建培训中心证书查询官网?
广州网站制作的公司,现在专门做网站的公司有没有哪几家是比较好的,性价比高,模板也多的?
孙琪峥织梦建站教程如何优化数据库安全?
制作农业网站的软件,比较好的农业网站推荐一下?
建站主机选购指南:核心配置优化与品牌推荐方案
Swift开发中switch语句值绑定模式
在线ppt制作网站有哪些软件,如何把网页的内容做成ppt?
制作销售网站教学视频,销售网站有哪些?
如何高效配置IIS服务器搭建网站?
建站之星后台密码如何安全设置与找回?
建站之星如何优化SEO以实现高效排名?
如何快速查询域名建站关键信息?
如何在阿里云域名上完成建站全流程?
深圳网站制作培训,深圳哪些招聘网站比较好?
如何做网站制作流程,*游戏网站怎么搭建?
网站制作价目表怎么做,珍爱网婚介费用多少?
建站之星后台管理系统如何操作?
已有域名和空间,如何快速搭建网站?
香港服务器网站卡顿?如何解决网络延迟与负载问题?
建站中国必看指南:CMS建站系统+手机网站搭建核心技巧解析
SAX解析器是什么,它与DOM在处理大型XML文件时有何不同?
公司网站的制作公司,企业网站制作基本流程有哪些?
重庆网站制作公司哪家好,重庆中考招生办官方网站?
*请认真填写需求信息,我们会在24小时内与您取得联系。