JavaScript创建对象的四种常用模式实例分析


Posted in Javascript onJanuary 11, 2019

本文实例讲述了JavaScript创建对象的四种常用模式。分享给大家供大家参考,具体如下:

这里介绍了javascript中创建对象常用的几种模式,包括:工厂模式,构造函数模式,原型模式,组合构造函数与原型的模式,动态原型模式。

一.工厂模式

看如下代码:

function getMySon(name,sex){
  var o={};
  o.name=name;
  o.sex=sex;
  o.sayName = function(){
    alert(this.name);
  }
  return o;
}
son1 = getMySon('li ming','male');
son2 = getMySon('li hong','female');

这就是工厂模式。在函数中定义一个对象,并为其添加属性与方法,最后将这个对象返回。虽然这种模式实现了方便的创建对象,但是有这样一个问题,即不能判断这个实例到底是谁创建的。

比如 son1 intanceof getMySon并不能返回 true。因为这里的实例确切来说并不是由getMySon 通过new来创建的,而是getMySon中的 o。
所以工厂模式并不适合需要创建很多种对象的情况。

那么怎么创建对象才能正确的判断实例是从哪儿来的呢?下面就要说到构造函数模式了。

二.构造函数模式

看如下代码 :

function getMySon(name,sex){
  this.name = name;
  this.sex = sex;
  this.sayName = function(){
    alert(this.name);
  }
}
son1 = new getMySon('li ming','female');

这就是构造函数模式,注意在调用时要用 new。

在进行new调用时,进行如下几个步骤:

1. 创建一个新的对象(并把空对象的__proto__属性设置为getMySon.prototype)。

2. 将构造函数的作用域赋给新对象(此时this 指向了这个新对象)。

3. 执行构造函数中的代码(通过this 为这个新对象添加属性)

4. 返回新对象。

通过这种方式产生的实例可以使用son1 instanceof getMySon来判断实例是由谁来产生的。

那么使用构造函数有什么问题呢?由于每次使用new时都会创建一个新的对象,那么所有的数据在不同实例之间是不共享的。但是对于函数sayName来说,它并没有必要创建多个。这样做浪费了空间。

这样就引出了下一种,原型模式。

三. 原型模式

看如下代码:

function getMySon(){}
getMySon.prototype.name = 'li ming';
getMySon.prototype.sex = 'female';
getMySon.prototype.sayName = function(){
  alert(this.name);
}

这就是原型模式(原型的相关知识这里不详细说)。

原型模式将属性和方法添加到了getMySon.prototype里,prototype由所有的实例共享,它只有一份,并不是所有的实例各有一份。

这种方式实现了让函数只有一份,不必占用多余的空间。但是,name,sex之类的属性并不需要在所有实例间共享,而且使用原型模式进行传参生成这些属性也不方便。

那么可以合并构造函数模式与原型模式,利用它们各自的优点。让各实例间不需要进行共享且需要通过传参进行生成的属性放在构造函数模式中生成,让各实例中需要共享的(比如方法)在原型模式中生成。

三. 组合构造函数与原型的模式

看如下代码:

function getMySon(name,sex){
  this.name=name;
  this.sex=sex;
}
getMySon.prototype.sayName(){
  alert(this.name);
}
son1=new getMySon('li ming','female');

这是 组合构造函数与原型的模式 。这种方式结合了构造函数模式与原型模式的优点。这是最常用的一种创建对象的模式。

四. 动态原型模式

所谓动态原型模式,其实是对 组合构造函数与原型的模式 的一种封装。
看如下代码:

function getMySon(name,sex){
  this.name = name;
  this.sex = sex;
  //即使有多个需要定义的方法,也只需判断一个方法。
  if(typeof sayName != 'function'){
    getMySon.prototype.sayName=function(){
      alert(this.name);
    }
  }
}
son1=new getMySon('li ming','female');

这里之所以命名为动态原型模式,是因为getMySon在不同的调用中会发生变化,是动态的。只有在第一次调用getMySon时才会执行对sayName函数的定义。
从本质来看,仍然是将不需共享的通过构造函数进行定义,需要共享的方法通过原型进行定义。只是将它们放在了一起,进行了封装。

感兴趣的朋友还可以使用本站在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行结果。

更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
制作特殊字的脚本
Jun 26 Javascript
sina的lightbox效果。
Jan 09 Javascript
再论Javascript下字符串连接的性能
Mar 05 Javascript
Js 获取Gridview选中行的内容操作步骤
Feb 05 Javascript
JS获取下拉列表所选中的TEXT和Value的实现代码
Jan 11 Javascript
原生JS实现-星级评分系统的简单实例
Aug 21 Javascript
js实现5秒倒计时重新发送短信功能
Feb 05 Javascript
Vue Socket.io源码解读
Feb 07 Javascript
微信小程序开发之改变data中数组或对象的某一属性值
Jul 05 Javascript
微信小程序tabBar设置实例解析
Nov 14 Javascript
详解Vue 单文件组件的三种写法
Feb 19 Javascript
springboot+vue+对接支付宝接口+二维码扫描支付功能(沙箱环境)
Oct 15 Javascript
详解Vue项目部署遇到的问题及解决方案
Jan 11 #Javascript
VeeValidate 的使用场景以及配置详解
Jan 11 #Javascript
JS函数节流和防抖之间的区分和实现详解
Jan 11 #Javascript
微信公众号H5支付接口调用方法
Jan 10 #Javascript
详解在Node.js中发起HTTP请求的5种方法
Jan 10 #Javascript
vue实现压缩图片预览并上传功能(promise封装)
Jan 10 #Javascript
微信小程序地图(map)组件点击(tap)获取经纬度的方法
Jan 10 #Javascript
You might like
curl不使用文件存取cookie php使用curl获取cookie示例
2014/01/26 PHP
ThinkPHP中自定义错误页面和提示页面实例
2014/11/22 PHP
ThinkPHP打开验证码页面显示乱码的解决方法
2014/12/18 PHP
Yii遍历行下每列数据的方法
2016/10/17 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
ThinkPHP5.1框架页面跳转及修改跳转页面模版示例
2019/05/06 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
TP5框架简单登录功能实现方法示例
2019/10/31 PHP
共享自己写一个框架DreamScript
2007/01/20 Javascript
jQuery的强大选择器小结
2009/12/27 Javascript
限制文本框输入N个字符的js代码
2010/05/13 Javascript
jQuery实现的立体文字渐变效果
2010/05/17 Javascript
解决ExtJS在chrome或火狐中正常显示在ie中不显示的浏览器兼容问题
2013/01/11 Javascript
js中widow.open()方法使用详解
2013/07/30 Javascript
jQuery实现“扫码阅读”功能
2015/01/21 Javascript
两种JavaScript的AES加密方式(可与Java相互加解密)
2016/08/02 Javascript
单行 JS 实现移动端金钱格式的输入规则
2017/05/22 Javascript
在Bootstrap开发框架中使用dataTable直接录入表格行数据的方法
2018/10/25 Javascript
Vue.js自定义指令学习使用详解
2019/10/19 Javascript
在vue-cli3中使用axios获取本地json操作
2020/07/30 Javascript
Python random模块用法解析及简单示例
2017/12/18 Python
Python爬虫爬取一个网页上的图片地址实例代码
2018/01/16 Python
css3实现背景图片拉伸效果像桌面壁纸一样
2013/08/19 HTML / CSS
园林技术个人的自我评价
2014/02/15 职场文书
单位工程竣工验收方案
2014/03/16 职场文书
文秘个人求职信范文
2014/04/22 职场文书
村抢险救灾方案
2014/05/09 职场文书
公司授权委托书范文
2014/09/21 职场文书
四风对照检查材料范文
2014/09/27 职场文书
给老婆的保证书
2015/01/16 职场文书
英语导游词
2015/02/13 职场文书
大学毕业谢师宴致辞
2015/07/27 职场文书
小学总务工作总结
2015/08/13 职场文书
2016年庆祝六一儿童节活动总结
2016/04/06 职场文书
Python基于Tkinter开发一个爬取B站直播弹幕的工具
2021/05/06 Python
Python利用FlashText算法实现替换字符串
2022/03/31 Python