详细分析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 相关文章推荐
CSS+JS构建的图片查看器
Jul 22 Javascript
B/S开发中常用javaScript技术与代码
Mar 09 Javascript
javascript 装载iframe子页面,自适应高度
Mar 20 Javascript
关于JQuery($.load)事件的用法和分析
Apr 09 Javascript
jquery、js调用iframe父窗口与子窗口元素的方法整理
Jul 31 Javascript
逐一介绍Jquery data()、Jquery stop()、jquery delay()函数(详)
Nov 04 Javascript
angularjs 表单密码验证自定义指令实现代码
Oct 27 Javascript
JavaScript之cookie技术详解
Nov 18 Javascript
JS使用正则截取两个字符串之间的字符串实现方法详解
Jan 06 Javascript
彻底理解js面向对象之继承
Feb 04 Javascript
layui点击按钮添加可编辑的一行方法
Aug 15 Javascript
jQuery使用ajax传递json对象到服务端及contentType的用法示例
Mar 12 jQuery
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中对数据库操作的封装
2006/10/09 PHP
用PHP 快速生成 Flash 动画的方法
2007/03/06 PHP
php程序之die调试法 快速解决错误
2009/09/17 PHP
php获取网卡的MAC地址支持WIN/LINUX系统
2014/04/30 PHP
PHP结合Jquery和ajax实现瀑布流特效
2016/01/07 PHP
jQuery解决下拉框select设宽度时IE 6/7/8下option超出显示不全
2013/05/27 Javascript
ListBox实现上移,下移,左移,右移的简单实例
2014/02/13 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
javascript实现仿IE顶部的可关闭警告条
2015/05/05 Javascript
jQuery中$this和$(this)的区别介绍(一看就懂)
2015/07/06 Javascript
js实现简单的计算器功能
2017/01/16 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
Angular 2父子组件数据传递之@Input和@Output详解(下)
2017/07/05 Javascript
Angular中自定义Debounce Click指令防止重复点击
2017/07/26 Javascript
详解vue2 $watch要注意的问题
2017/09/08 Javascript
给localStorage设置一个过期时间的方法分享
2018/11/06 Javascript
微信运维交互机器人的示例代码
2018/11/12 Javascript
JavaScript实现美化滑块效果
2019/05/17 Javascript
vue draggable resizable gorkys与v-chart使用与总结
2019/09/05 Javascript
微信小程序 轮播图实现原理及优化详解
2019/09/29 Javascript
解决vue组件没显示,没起作用,没报错,但该显示的组件没显示问题
2020/09/02 Javascript
原生JS实现京东查看商品点击放大
2020/12/21 Javascript
Python函数嵌套实例
2014/09/23 Python
Python统计文件中去重后uuid个数的方法
2015/07/30 Python
Python分治法定义与应用实例详解
2017/07/28 Python
Python如何生成树形图案
2018/01/03 Python
对python实现合并两个排序链表的方法详解
2019/01/23 Python
使用Python进行中文繁简转换的实现代码
2019/10/18 Python
Lancome兰蔻官方旗舰店:来自法国的世界知名美妆品牌
2018/06/14 全球购物
英国蜡烛、蜡烛配件和家居香氛购买网站:Yankee Candle
2018/12/12 全球购物
什么是Smarty变量操作符?如何使用Smarty变量操作符
2014/07/18 面试题
linux面试题参考答案(11)
2016/11/26 面试题
党员批评与自我批评总结
2014/10/15 职场文书
工作疏忽检讨书500字
2014/10/26 职场文书
基于Redis过期事件实现订单超时取消
2021/05/08 Redis