详细分析Javascript中创建对象的四种方式


Posted in Javascript onAugust 17, 2016

前言

使用Javascript创建对象的方式有很多,现在就来列举一下其中的四种方式,并且罗列出了每种方式的优缺点,可以让大家进行选择使用,下面来看看。

工厂模式

function createPerson(name, age){
 var obj = new Object();
 obj.name = name;
 obj.age = age;
 return obj; //一定要返回,否则打印undefined:undefined
 }
 var person1 = new createPerson('Young',18);
 console.log(person1.name + ':' + person1.age);

优点:工厂模式可以解决创建多个相似对象

缺点:没有解决对象识别问题(怎样确定一个对象的类型)

构造函数模式

function Person(name,age){
 this.name = name;
 this.age = age;
 }
 var person1 = new Person('Young',18);
 console.log(person1.name + ':' + person1.age);

在说优缺点之前,先来说说她本身的一点小故事吧

将构造函数当做函数使用

function Person(name,age){
 this.name=name;
 this.age=age;
 this.sayName=function(){
 return this.name;
 }
 }
 
 //当做构造函数使用
 var person1 = new Person('Young', 18);
 person1.sayName();
 console.log(person1.name + ':' + person1.age);
 
 //当做普通函数调用
 Person('Wind', 18);
 console.log(window.sayName());
 
 //在另一个作用域中调用
 var obj = new Object();
 Person.call(obj, 'bird', 100);
 console.log(obj.sayName());

构造函数优缺点

优点:可以将它的实例标识为一种特定类型

缺点:每个方法都要在每个实例上重新创建一遍。当然你也可以这样改:

function Person(name, age){
 this.name = name;
 this.age = age;
 this.sayName = sayName;
 }
 function sayName(){
 return this.name;
 }

改为调用全局函数,这样一来毫无封装性可言。。。接下来的原型模式可以弥补这个的不足

原型模式

function Person(){
 
 }
 Person.prototype.name = 'Young';
 Person.prototype.age = 18;
 Person.prototype.sayName = function(){
 return this.name;
 }
 
 var person1 = new Person();
 console.log(person1.sayName());
 var person2 = new Person();
 console.log(person1.sayName());
 alert(person1.sayName === person2.sayName);
 //person1和person2访问的是同一组属性的同一个sayName()函数

虽然可以通过对象实例访问保存在原型中的值,但却不能通过实例对象重写原型中的值

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var person1=new Person();
 var person2=new Person();
 person1.name='Wind';
 
 console.log(person1.sayName());//Wind
 console.log(person2.sayName());//Young
 alert(person1.sayName==person2.sayName);//true

在我们调用person1.sayName的时候,会先后执行两次搜索,解析器先确定实例person1是否有sayName的属性,有则调用自己的属性,没有则搜索原型中的属性。

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var person1=new Person();
 var person2=new Person();
 
 person1.name='Wind';
 console.log(person1.sayName());//Wind
 console.log(person2.sayName());//Young
 
 delete person1.name;
 console.log(person1.sayName());//Young
 console.log(person2.sayName());//Young

使用hasOwnPropertyType方法可以检测一个属性是存在与原型中还是存在于实例中,该方法是从Object继承来的,实例中为true,原型中为false。

枚举对象上的实例属性用Object.keys()方法

function Person(){
 
 }
 Person.prototype.name='Young';
 Person.prototype.age=18;
 Person.prototype.sayName=function(){
 return this.name;
 }
 
 var keys=Object.keys(Person.prototype);
 console.log(keys);//["name", "age", "sayName"]

原型模式优缺点

优点:不用每个方法都要在每个实例上重申一遍

缺点:很少有人单独使用原型模式地。。问题详列

function Person(){
 
 }
 Person.prototype={
 constructor:Person,
 name:'Young',
 age:18,
 friends:['Big','Pig'],
 sayName:function(){
 return this.name;
 }
 };
 var p1=new Person();
 var p2=new Person();
 p1.friends.push('Mon');
 console.log(p1.friends);//["Big", "Pig", "Mon"]
 console.log(p2.friends);//["Big", "Pig", "Mon"]

正是因为实例一般都要有自己的属性,而我们这里将他放在了Person.prototype中,所以随着p1的修改,整个实例包括原型都修改了。那么,我们可以组合使用构造函数模式和原型模式。

组合使用构造函数模式和原型模式

function Person(name,age){
 this.name=name;
 this.age=age;
 this.friends=['Big','Pig'];
 }
 Person.prototype={
 sayName:function(){
 return this.name;
 }
 };
 var p1=new Person('Young',18);
 var p2=new Person('Wind',78);
 p1.friends.push('Raganya');
 console.log(p1.friends);//["Big", "Pig", "Raganya"]
 console.log(p2.friends);//["Big", "Pig"]
 console.log(p1.friends==p2.friends);//false
 console.log(p1.sayName==p2.sayName);//true

这种模式是目前使用最广泛、认同度最高的一种创建自定义类型的方法。是用来定义引用类型的一种默认模式。

总结

以上就是关于分析Javascript中创建对象方式的全部内容,通过这篇文章为大家总结的四种方式和其优缺点,希望可以对大家学习使用Javascript能有所帮助。

Javascript 相关文章推荐
js 未结束的字符串常量错误解决方法
Jun 13 Javascript
JS延迟加载加快页面打开速度示例代码
Dec 30 Javascript
获取select元素被选中的文本内容的js代码
Jan 29 Javascript
jQuery CSS3相结合实现时钟插件
Jan 08 Javascript
Vue.js快速入门教程
Sep 07 Javascript
JS实现类似百叶窗下拉菜单效果
Dec 30 Javascript
Canvas放置反弹效果随机图形(实例)
Aug 17 Javascript
微信小程序实现时间预约功能
Nov 27 Javascript
Vue开发之watch监听数组、对象、变量操作分析
Apr 25 Javascript
layer弹出层显示在top顶层的方法
Sep 11 Javascript
webpack打包html里面img后src为“[object Module]”问题
Dec 22 Javascript
Vue项目如何引入bootstrap、elementUI、echarts
Nov 26 Vue.js
AngularJS表单详解及示例代码
Aug 17 #Javascript
AngularJS模块详解及示例代码
Aug 17 #Javascript
Bootstrap 源代码分析(未完待续)
Aug 17 #Javascript
AngularJS HTML DOM详解及示例代码
Aug 17 #Javascript
AngularJS表格详解及示例代码
Aug 17 #Javascript
AngularJS过滤器详解及示例代码
Aug 16 #Javascript
AngularJS控制器详解及示例代码
Aug 16 #Javascript
You might like
php中mt_rand()随机数函数用法
2014/11/24 PHP
php+mysqli实现批量替换数据库表前缀的方法
2014/12/29 PHP
CI配置多数据库访问的方法
2016/03/28 PHP
laravel多条件查询方法(and,or嵌套查询)
2019/10/09 PHP
通过ifame指向的页面高度调整iframe的高度
2006/10/05 Javascript
jQuery 类twitter的文本字数限制带提示效果插件
2010/04/16 Javascript
用JQuery调用Session的实现代码
2010/10/29 Javascript
cnblogs中在闪存中屏蔽某人的实现代码
2010/11/14 Javascript
js原生态函数中使用jQuery中的 $(this)无效的解决方法
2011/05/25 Javascript
javascript五图轮播切换实用版
2012/08/17 Javascript
jQuery操作CheckBox的方法介绍(选中,取消,取值)
2014/02/04 Javascript
JS往数组中添加项性能分析
2015/02/25 Javascript
JavaScript的继承实现小结
2017/05/07 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
详解vuex中mapState,mapGetters,mapMutations,mapActions的作用
2018/04/13 Javascript
Webpack中雪碧图插件使用详解
2018/05/25 Javascript
[原创]微信小程序获取网络类型的方法示例
2019/03/01 Javascript
vue 地图可视化 maptalks 篇实例代码详解
2019/05/21 Javascript
react 移动端实现列表左滑删除的示例代码
2019/07/04 Javascript
微信小程序按钮点击动画效果的实现
2019/09/04 Javascript
python Socket之客户端和服务端握手详解
2017/09/18 Python
Django后端接收嵌套Json数据及解析详解
2019/07/17 Python
对Django外键关系的描述
2019/07/26 Python
python找出列表中大于某个阈值的数据段示例
2019/11/24 Python
PyQt5实现画布小程序
2020/05/30 Python
python3让print输出不换行的方法
2020/08/24 Python
利用python清除移动硬盘中的临时文件
2020/10/28 Python
一套.net面试题及答案
2016/11/02 面试题
普通话演讲稿
2014/09/03 职场文书
歌颂党的演讲稿
2014/09/10 职场文书
2014大学生批评与自我批评思想汇报
2014/09/21 职场文书
2015年办公室人员工作总结
2015/05/15 职场文书
礼貌问候语大全
2015/11/10 职场文书
中小学教师继续教育心得体会
2016/01/19 职场文书
创业计划书之网吧
2019/10/10 职场文书
Linux系统下MySQL配置主从分离的步骤
2022/03/21 MySQL