JS创建对象几种不同方法详解


Posted in Javascript onMarch 01, 2016

本文介绍了几种js创建对象的方法,分享给大家供大家参考,具体内容如下

1、工厂模式

弊端:没有解决对象的识别问题,即怎么知道一个对象的类型。

JS创建对象几种不同方法详解

2、构造函数模式

JS创建对象几种不同方法详解 

与工厂模式相比:
1、没有显式的创建对象
2、直接将属性和方法赋给了this对象
3、没有return语句
要创建person的实例,必须使用new操作符,以这种方式调用构造函数实际上会经历4个步骤:
1、创建一个新对象
2、将构造函数的作用域赋给新对象
3、执行构造函数中的代码
4、返回新对象
创建自定义的构造函数可以将它的实例标识为一种特定的类型。
构造函数的缺点:
每个方法都有在每个实例上重新创建一遍。person1和person2都有一个sayName()的方法,但两个方法不是同一个Function实例。不同实例上的同名函数是不相等的。
创建两个完成同样任务的Function实例没有必要,而且还有this对象在,不需要在执行代码前就把函数绑定在特定对象上,可以像下面这样。

JS创建对象几种不同方法详解 

把sayName属性设置成全局的sayName函数,这样,由于sayName包含的是一个指向函数的指针,因此person1和person2对象就共享了同一个函数。
但是,如果对象需要定义很多方法,那么就要定义很多全局函数,自定义的引用类型也没有封装可言了。为了解决上述问题,引入原型模式。

3、原型模式

理解原型对象
我们创建的每个函数都有一个prototype属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。prototype是通过调用构造函数而创建的那个对象实例的对象原型,使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

JS创建对象几种不同方法详解 

首先,解析器会问实例person1是否有name属性,如果有,就返回。
如果没有,就继续去person1的原型中搜索name属性,如果有就返回。
如果没有,再继续向person1的原型的原型中搜索。

JS创建对象几种不同方法详解 

isPrototypeOf()确定实例和原型对象之间的关联
console.log(Person.prototype.isPrototypeOf(person1)); //true
Object.getPrototypeOf()返回的是[[prototype]]的值
console.log(Object.getPrototypeOf(person1));
//Person {name: “Yvette”, age: 26, job: “engineer”} 返回的是Person的原型对象。
console.log(Object.getPrototypeOf(person1) === Person.prototype)//true
console.log(Object.getPrototypeOf(person1).name);//”Yvette”
hasOwnProperty()方法可以检测一个属性是存在于实例中,还是存在于原型中,只有给定属性存在于实例中,才会返回true。
console.log(person1.hasOwnProperty(“name”));//false
原型与in操作符
有两种方式使用in操作符:单独使用和在for-in循环中使用。单独使用时,in操作符会在通过对象能够访问给定属性时返回true,无论该属性在于实例中还是原型中。
使用for in循环,返回的是所有能够通过对象访问的、可枚举的属性,其中既包括实例中的属性,也包括存在于原型中的属性。如果实例中的属性屏蔽了原型中不可枚举的属性,那么也会返回。IE9之前的版本实现上有一个Bug,屏蔽不可枚举属性的实例属性不会在for-in中返回。

JS创建对象几种不同方法详解 

在IE9之前的吧按本中没有log信息。尽管person实例中的toString()方法屏蔽了原型中的不可 枚举的toString();
原型简写

JS创建对象几种不同方法详解 

这导致了person1.constructor不再指向Person,而是指向了Object。如果constructor很重要,则需要特意将其设为适当的值,如:

JS创建对象几种不同方法详解 

但是这种方式会导致constructor属性变成可枚举。
如果想设置为不可枚举的(默认不可枚举),可以使用Object.defineProperty(Person.prototype, “constructor”, {
enumerable: false,
value: Person
});
原型的动态性
由于在原型中查找值的过程是一次搜索,因此我们对原型对象所做的任何修改都能够立即从实例上反映出来。
如果重写整个原型对象,情况就不一样了。调用构造函数时会为实例添加一个指向最初原型的[[prototype]]指针,而把原型修改为另外一个对象就等于切断了构造函数与最初原型之间的联系。实例中的指针仅指向原型,而不指向构造函数。

JS创建对象几种不同方法详解 

person.prototype指向的是原本的原型对象,而不会指向新的原型对象。
原型对象的问题
原型模式最大问题是由其共享的本性所导致的。
对于包含引用类型值的属性来说,问题较为突出

JS创建对象几种不同方法详解 

本意只想修改person1的friends,但是却导致person2的friends属性值也改变了。因此我们很少单独使用原型模式。

4、组合使用构造模式和原型模式

创建自定义类型的最常用的方式,就是组合使用构造函数模式与原型模式。构造函数模式用于定义实例属性,原型模式用于定义方法和共享的属性,这样每个实例都有自己的一份实例属性的副本,又同时共享着对方法的引用,最大限度的节省了内存。
JS创建对象几种不同方法详解 

除了以上几种方式以外,另外还有动态原型模式,寄生构造模式和稳妥构造模式,但是鉴于使用频率较低,不再赘述。

Javascript 相关文章推荐
js调试工具console.log()方法查看js代码的执行情况
Aug 08 Javascript
jQuery实现简单的间隔向上滚动效果
Mar 09 Javascript
js内置对象处理_打印学生成绩单的简单实现
Sep 24 Javascript
JavaScript简单实现合并两个Json对象的方法示例
Oct 16 Javascript
详解vue axios二次封装
Jul 22 Javascript
js监听html页面的上下滚动事件方法
Sep 11 Javascript
Easyui 关闭jquery-easui tab标签页前触发事件的解决方法
Apr 28 jQuery
node.js实现上传文件功能
Jul 15 Javascript
Flutter 超实用简单菜单弹出框 PopupMenuButton功能
Aug 06 Javascript
vue element 生成无线级左侧菜单的实现代码
Aug 21 Javascript
在vscode 中设置 vue模板内容的方法
Sep 02 Javascript
JavaScript实现显示和隐藏图片
Apr 29 Javascript
jQuery中通过ajax的get()函数读取页面的方法
Feb 29 #Javascript
基于JavaScript实现文字超出部分隐藏
Feb 29 #Javascript
基于JavaScript实现百叶窗动画效果不只单纯flas可以实现
Feb 29 #Javascript
ClearTimeout消除闪动实例代码
Feb 29 #Javascript
JavaScript实现点击按钮字体放大、缩小
Feb 29 #Javascript
jquery trigger函数执行两次的解决方法
Feb 29 #Javascript
理解js回收机制通俗易懂版
Feb 29 #Javascript
You might like
优化PHP代码的53条建议
2008/03/27 PHP
Yii Framework框架获取分类下面的所有子类方法
2014/06/20 PHP
thinkphp文件引用与分支结构用法实例
2014/11/26 PHP
PHP连接SQLServer2005的方法
2015/01/27 PHP
详解WordPress中用于合成数组的wp_parse_args()函数
2015/12/18 PHP
支付宝服务窗API接口开发php版本
2016/07/20 PHP
浅谈php使用curl模拟多线程发送请求
2019/03/08 PHP
JavaScript中的几个关键概念的理解-原型链的构建
2011/05/12 Javascript
如何设置一定时间内只能发送一次请求
2014/02/28 Javascript
javascript学习笔记(二)数组和对象部分
2014/09/30 Javascript
Nodejs极简入门教程(三):进程
2014/10/27 NodeJs
jquery遍历table的tr获取td的值实现方法
2016/05/19 Javascript
jQuery插件EasyUI实现Layout框架页面中弹出窗体到最顶层效果(穿越iframe)
2016/08/05 Javascript
jQuery基于事件控制实现点击显示内容下拉效果
2017/03/07 Javascript
微信小程序 后台登录(非微信账号)实例详解
2017/03/31 Javascript
基于hover的用法实例(推荐)
2017/07/04 Javascript
微信小程序按钮去除边框线分享页面功能
2018/08/27 Javascript
vue基础之事件简写、事件对象、冒泡、默认行为、键盘事件实例分析
2019/03/11 Javascript
简单了解JavaScript作用域
2020/07/31 Javascript
[02:38]2018DOTA2亚洲邀请赛赛前采访-VGJ.T
2018/04/03 DOTA
[01:51]历届DOTA2国际邀请赛举办地回顾 TI9落地上海
2018/08/26 DOTA
[01:12:40]DOTA2-DPC中国联赛 正赛 DLG vs XG BO3 第三场 1月25日
2021/03/11 DOTA
Python对List中的元素排序的方法
2018/04/01 Python
python在TXT文件中按照某一字符串取出该字符串所在的行方法
2018/12/10 Python
python爬取百度贴吧前1000页内容(requests库面向对象思想实现)
2019/08/10 Python
pycharm不能运行.py文件的解决方法
2020/02/12 Python
python 监控logcat关键字功能
2020/09/04 Python
python 绘制国旗的示例
2020/09/27 Python
html5实现输入框fixed定位在屏幕最底部兼容性
2020/07/03 HTML / CSS
双立人加拿大官网:Zwilling加拿大
2020/08/10 全球购物
给酒店员工的表扬信
2014/01/11 职场文书
优秀求职信范文分享
2014/01/26 职场文书
工人先锋号事迹材料
2014/12/24 职场文书
实习生辞职信范文
2015/03/02 职场文书
mysql如何能有效防止删库跑路
2021/10/05 MySQL
Oracle使用别名的好处
2022/04/19 Oracle