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 相关文章推荐
javascript函数以及基础写法100多条实用整理
Jan 13 Javascript
JS两种定义方式的区别、内部原理
Nov 21 Javascript
JSON中双引号的轮回使用过程中一定要小心
Mar 05 Javascript
Node.js(安装,启动,测试)
Jun 09 Javascript
底部悬浮通栏可以关闭广告位的实现方法
Jun 01 Javascript
JS全局变量和局部变量最新解析
Jun 24 Javascript
jquery遍历标签中自定义的属性方法
Sep 17 Javascript
input输入密码变黑点密文的实现方法
Jan 09 Javascript
使用jQuery实现动态添加小广告
Jul 11 jQuery
QQ跳转支付宝并自动领红包脚本(最新)
Jun 22 Javascript
世界上最短的数字判断js代码
Sep 09 Javascript
javascript实现随机抽奖功能
Dec 30 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
php面向对象的方法重载两种版本比较
2008/09/08 PHP
php 无限级数据JSON格式及JS解析
2010/07/17 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
2015/04/03 PHP
php通过smtp邮件验证登陆的方法
2016/05/11 PHP
PHP实现的获取文件mimes类型工具类示例
2018/04/08 PHP
yii2 上传图片的示例代码
2018/11/02 PHP
使用JavaScript检测Firefox浏览器是否启用了Firebug的代码
2010/12/28 Javascript
基于jquery tab切换(防止页面刷新)
2012/05/23 Javascript
jquery焦点图片切换(数字标注/手动/自动播放/横向滚动)
2013/01/24 Javascript
js实现图片无缝滚动特效
2020/03/19 Javascript
JS组件Bootstrap dropdown组件扩展hover事件
2016/04/17 Javascript
Angular2入门教程之模块和组件详解
2017/05/28 Javascript
JS查找数组中重复元素的方法详解
2017/06/14 Javascript
小程序封装wx.request请求并创建接口管理文件的实现
2019/04/29 Javascript
vue 图片裁剪上传组件的实现
2020/11/12 Javascript
[39:46]完美世界DOTA2联赛PWL S2 LBZS vs Rebirth 第二场 11.25
2020/11/25 DOTA
Tornado Web服务器多进程启动的2个方法
2014/08/04 Python
详解C++编程中一元运算符的重载
2016/01/19 Python
PyQt5 窗口切换与自定义对话框的实例
2019/06/20 Python
Python Subprocess模块原理及实例
2019/08/26 Python
多版本python的pip 升级后, pip2 pip3 与python版本失配解决方法
2019/09/11 Python
利用python画出AUC曲线的实例
2020/02/28 Python
使用CSS3代码绘制可爱的Hello Kitty猫
2016/08/03 HTML / CSS
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
html5 横向滑动导航栏的方法示例
2020/05/08 HTML / CSS
简历自我评价怎么写好呢?
2014/01/04 职场文书
学生实习介绍信
2014/01/15 职场文书
争论的故事教学反思
2014/02/06 职场文书
财政局党的群众路线教育实践活动剖析材料
2014/10/13 职场文书
邀请函范文
2015/02/02 职场文书
感恩节寄语2015
2015/03/24 职场文书
培训计划通知
2015/07/15 职场文书
幼儿园师德师风心得体会
2016/01/12 职场文书
微信小程序实现录音Record功能
2021/05/09 Javascript
Mysql binlog日志文件过大的解决
2021/10/05 MySQL