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 相关文章推荐
jquery判断checkbox(复选框)是否被选中的代码
Oct 20 Javascript
js/jquery去掉空格,回车,换行示例代码
Nov 05 Javascript
Jquery 改变radio/checkbox选中状态,获取选中的值(示例代码)
Dec 12 Javascript
js实现简单的购物车有图有代码
May 26 Javascript
jquery解决客户端跨域访问问题
Jan 06 Javascript
AngularJS基础学习笔记之简单介绍
May 10 Javascript
非常实用的js验证框架实现源码 附原理方法
Jun 08 Javascript
jQuery操作iframe中js函数的方法小结
Jul 06 Javascript
ES6关于Promise的用法详解
May 07 Javascript
详解如何解决Vue和vue-template-compiler版本之间的问题
Sep 17 Javascript
JavaScript数组特性与实践应用深入详解
Dec 30 Javascript
通过js给网页加上水印背景实例
Jun 17 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
smarty模板引擎中自定义函数的方法
2015/01/22 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
JavaScript中json对象和string对象之间相互转化
2012/12/26 Javascript
jquery对dom的操作常用方法整理
2013/06/25 Javascript
JavaScript中setAttribute用法介绍
2013/07/20 Javascript
js点击出现悬浮窗效果不使用JQuery插件
2014/01/20 Javascript
深入理解JavaScript系列(33):设计模式之策略模式详解
2015/03/03 Javascript
JavaScript制作简易的微信打飞机
2015/03/31 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
JavaScript中使用concat()方法拼接字符串的教程
2015/06/06 Javascript
超实用的JavaScript代码段 附使用方法
2016/05/22 Javascript
JS 拼凑字符串的简单实例
2016/09/02 Javascript
vue文件树组件使用详解
2018/03/29 Javascript
vue框架搭建之axios使用教程
2018/07/11 Javascript
vue2.0 中使用transition实现动画效果使用心得
2018/08/13 Javascript
详解Vue改变数组中对象的属性不重新渲染View的解决方案
2018/09/21 Javascript
微信小程序实现授权登录
2019/05/15 Javascript
学习RxJS之JavaScript框架Cycle.js
2019/06/17 Javascript
js new Date()实例测试
2019/10/31 Javascript
浅谈vue-props的default写不写有什么区别
2020/08/09 Javascript
学习python类方法与对象方法
2016/03/15 Python
75条笑死人的知乎神回复,用60行代码就爬完了
2019/05/06 Python
python 多线程死锁问题的解决方案
2020/08/25 Python
浅析PyCharm 的初始设置(知道)
2020/10/12 Python
AmazeUI 面板的实现示例
2020/08/17 HTML / CSS
俄罗斯韩国化妆品网上商店:Cosmasi.ru
2019/10/31 全球购物
Java里面如何把一个Array数组转换成Collection, List
2013/07/26 面试题
小学生个人先进事迹材料
2014/05/08 职场文书
多媒体教室标语
2014/06/26 职场文书
交通违章检讨书
2014/09/21 职场文书
大三学年自我鉴定范文(3篇)
2014/09/28 职场文书
县级领导干部开展党的群众路线教育实践活动工作汇报
2014/10/25 职场文书
2014村书记党建工作汇报材料
2014/11/02 职场文书
计算机实训报告总结
2014/11/05 职场文书
Python初学者必备的文件读写指南
2021/06/23 Python
一次MySQL启动导致的事故实战记录
2021/09/15 MySQL