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 相关文章推荐
js 多浏览器分别判断代码
Apr 01 Javascript
javascript中[]和{}对象使用介绍
Mar 20 Javascript
jQuery随便控制任意div隐藏的方法
Jun 28 Javascript
jQuery自定义元素右键点击事件(实现案例)
Apr 28 jQuery
解决BootStrap Fileinput手机图片上传显示旋转问题
Jun 01 Javascript
vue渲染时闪烁{{}}的问题及解决方法
Mar 28 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
Sep 03 jQuery
vue-自定义组件传值的实例讲解
Sep 18 Javascript
在vue中多次调用同一个定义全局变量的实例
Sep 25 Javascript
javascript单张多张图无缝滚动实例代码
May 10 Javascript
Vue自定义render统一项目组弹框功能
Jun 07 Javascript
详解实现vue的数据响应式原理
Jan 20 Vue.js
详解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操作xml代码
2010/06/17 PHP
php class中public,private,protected的区别以及实例分析
2013/06/18 PHP
php去掉URL网址中带有PHPSESSID的配置方法
2014/07/08 PHP
php使用cookie保存用户登录的用户名实例
2015/01/26 PHP
php+xml结合Ajax实现点赞功能完整实例
2015/01/30 PHP
php一个解析字符串排列数组的方法
2015/05/12 PHP
浅析php静态方法与非静态方法的用法区别
2016/05/17 PHP
PHP从零开始打造自己的MVC框架之路由类实现方法分析
2019/06/03 PHP
Prototype Class对象学习
2009/07/19 Javascript
一个简单的JS鼠标悬停特效具体方法
2013/06/17 Javascript
javascript的内存管理详解
2013/08/07 Javascript
jquery选择器、属性设置用法经验总结
2013/09/08 Javascript
jQuery对html元素取值与赋值的方法
2013/11/20 Javascript
Dojo Javascript 编程规范 规范自己的JavaScript书写
2014/10/26 Javascript
js控制文本框禁止输入特殊字符详解
2017/04/07 Javascript
浅谈React Event实现原理
2018/09/20 Javascript
vue-cli的工程模板与构建工具详解
2018/09/27 Javascript
JavaScript检测是否开启了控制台(F12调试工具)
2020/10/02 Javascript
python数据结构之二叉树的建立实例
2014/04/29 Python
简单的Python抓taobao图片爬虫
2014/10/26 Python
python使用正则表达式提取网页URL的方法
2015/05/26 Python
老生常谈Python序列化和反序列化
2017/06/28 Python
Python3多线程爬虫实例讲解代码
2018/01/05 Python
Python实现拷贝/删除文件夹的方法详解
2018/08/29 Python
基于Python共轭梯度法与最速下降法之间的对比
2020/04/02 Python
利用python+ffmpeg合并B站视频及格式转换的实例代码
2020/11/24 Python
数字天堂软件测试面试题
2012/12/23 面试题
师范毕业生自我鉴定
2014/01/15 职场文书
2014爱耳日宣传教育活动总结
2014/03/09 职场文书
生物科学专业自荐书
2014/06/20 职场文书
注册资产评估专业求职信
2014/07/16 职场文书
学习焦裕禄同志为人民服务思想汇报
2014/09/10 职场文书
出纳试用期工作总结2015
2015/05/28 职场文书
创业计划书之农家乐
2019/10/09 职场文书
导游词之台湾安平古堡
2019/12/25 职场文书
mysql 乱码 字符集latin1转UTF8
2022/04/19 MySQL