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事件冒泡传递(cancelBubble 、stopPropagation)
May 08 Javascript
javascript 多种搜索引擎集成的页面实现代码
Jan 02 Javascript
jquery.simple.tree插件 更简单,兼容性更好的无限树插件
Sep 03 Javascript
ASP.NET jQuery 实例15 通过控件CustomValidator验证CheckBoxList
Feb 03 Javascript
Node.js 服务器端应用开发框架 -- Hapi.js
Jul 29 Javascript
jQuery动态添加及删除表单上传元素的方法(附demo源码下载)
Jan 15 Javascript
js调用父框架函数与弹窗调用父页面函数的简单方法
Nov 01 Javascript
JavaScript截屏功能的实现代码
Jul 28 Javascript
javaScript日期工具类DateUtils详解
Dec 08 Javascript
JavaScript事件发布/订阅模式原理与用法分析
Aug 21 Javascript
微信小程序点击保存图片到本机功能
Dec 13 Javascript
VSCode 配置uni-app的方法
Jul 11 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
一个程序下载的管理程序(一)
2006/10/09 PHP
完美实现GIF动画缩略图的php代码
2011/01/02 PHP
PHP 5.6.11 访问SQL Server2008R2的几种情况详解
2016/08/08 PHP
Thinkphp5.0 框架视图view的比较标签用法分析
2019/10/12 PHP
利用Dojo和JSON建立无限级AJAX动态加载的功能模块树
2007/03/24 Javascript
js中查找最近的共有祖先元素的实现代码
2010/12/30 Javascript
Lazy Load 延迟加载图片的jQuery插件中文使用文档
2012/10/18 Javascript
JS继承用法实例分析
2015/02/05 Javascript
jQuery实现仿百度帖吧头部固定导航效果
2015/08/07 Javascript
全面解析JavaScript中“&&”和“||”操作符(总结篇)
2016/07/18 Javascript
以BootStrap Tab为例写一个前端组件
2017/07/25 Javascript
详解JavaScript按概率随机生成事件
2017/08/02 Javascript
react-native DatePicker日期选择组件的实现代码
2017/09/12 Javascript
微信小程序radio组件使用详解
2018/01/31 Javascript
详解基于Node.js的HTTP/2 Server实践
2018/05/31 Javascript
老生常谈JS中的继承及实现代码
2018/07/06 Javascript
详解Vue.js使用Swiper.js在iOS
2018/09/10 Javascript
vue路由事件beforeRouteLeave及组件内定时器的清除方法
2018/09/29 Javascript
Vue自定义指令写法与个人理解
2019/02/09 Javascript
JavaScript定时器使用方法详解
2020/03/26 Javascript
[45:18]2018DOTA2亚洲邀请赛 4.3 突围赛 Optic vs iG 第一场
2018/04/04 DOTA
[41:13]完美世界DOTA2联赛PWL S2 Forest vs Rebirth 第一场 11.20
2020/11/20 DOTA
Python中利用sqrt()方法进行平方根计算的教程
2015/05/15 Python
Python将8位的图片转为24位的图片实现方法
2018/10/24 Python
解决torch.autograd.backward中的参数问题
2020/01/07 Python
使用python 计算百分位数实现数据分箱代码
2020/03/03 Python
Python网页解析器使用实例详解
2020/05/30 Python
Python3 用matplotlib绘制sigmoid函数的案例
2020/12/11 Python
Python 多进程原理及实现
2020/12/21 Python
贝玲妃美国官方网站:Benefit美国
2016/08/28 全球购物
美国男士内衣品牌:Tommy John
2017/12/22 全球购物
个人找工作自荐信格式
2013/09/21 职场文书
小学岗位竞聘方案
2014/01/22 职场文书
补充协议书范本
2014/04/23 职场文书
2014国庆节国旗下演讲稿(精选版)
2014/09/26 职场文书
JavaScript分页组件使用方法详解
2021/07/26 Javascript