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 获取所有id中包含某关键字的控件的实现代码
Nov 25 Javascript
JavaScript设置body高度为浏览器高度的方法
Feb 09 Javascript
比例尺、缩略图、平移缩放之百度地图添加控件方法
Aug 03 Javascript
JavaScript操作URL的相关内容集锦
Oct 29 Javascript
详解JavaScript中localStorage使用要点
Jan 13 Javascript
JavaScript驾驭网页-CSS与DOM
Mar 24 Javascript
JS HTML5拖拽上传图片预览
Jul 18 Javascript
利用React-router+Webpack快速构建react程序
Oct 27 Javascript
使用原生的javascript来实现轮播图
Feb 24 Javascript
react+redux的升级版todoList的实现
Dec 18 Javascript
JS中call()和apply()的功能及用法实例分析
Jun 28 Javascript
layui使用label标签的方法
Sep 14 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制作简单分页(从数据库读取记录)的方法详解
2013/05/04 PHP
php获取文件夹路径内的图片以及分页显示示例
2014/03/11 PHP
PHP间隔一段时间执行代码的方法
2014/12/02 PHP
PHP面向对象程序设计继承用法简单示例
2018/12/28 PHP
PHP Laravel中的Trait使用方法
2019/01/20 PHP
js玩一玩WSH吧
2007/02/23 Javascript
input 高级限制级用法
2009/03/26 Javascript
原生js仿jquery实现对Ajax的封装
2016/10/04 Javascript
JavaScript排序算法动画演示效果的实现方法
2016/10/18 Javascript
微信小程序中多个页面传参通信的学习与实践
2017/05/05 Javascript
详解.vue文件中监听input输入事件(oninput)
2017/09/19 Javascript
微信小程序实现YDUI的ScrollNav组件
2018/02/02 Javascript
vue form 表单提交后刷新页面的方法
2018/09/04 Javascript
Vue.js 实现数据展示全部和收起功能
2018/09/05 Javascript
js图片无缝滚动插件使用详解
2020/05/26 Javascript
JS实现纵向轮播图(初级版)
2020/01/18 Javascript
ant design vue嵌套表格及表格内部编辑的用法说明
2020/10/28 Javascript
[02:35]DOTA2英雄基础教程 狙击手
2014/01/14 DOTA
python查询sqlite数据表的方法
2015/05/08 Python
Python网络爬虫项目:内容提取器的定义
2016/10/25 Python
python对常见数据类型的遍历解析
2019/08/27 Python
Python 3.6 中使用pdfminer解析pdf文件的实现
2019/09/25 Python
python几种常用功能实现代码实例
2019/12/25 Python
scrapy爬虫:scrapy.FormRequest中formdata参数详解
2020/04/30 Python
Django使用django-simple-captcha做验证码的实现示例
2021/01/07 Python
python上下文管理的使用场景实例讲解
2021/03/03 Python
html5中地理位置定位api接口开发应用小结
2013/01/04 HTML / CSS
Clarins娇韵诗英国官网:来自法国的天然护肤品牌
2017/04/18 全球购物
省优秀教师事迹材料
2014/01/30 职场文书
企业总经理岗位职责
2014/02/13 职场文书
优秀护士事迹材料
2014/12/25 职场文书
2015年药房工作总结
2015/04/25 职场文书
大学生受助感言
2015/08/01 职场文书
python实现自定义日志的具体方法
2021/05/28 Python
零基础学java之带返回值的方法的定义和调用
2022/04/10 Java/Android
关于vue-router-link选择样式设置
2022/04/30 Vue.js