JavaScript创建对象方式总结【工厂模式、构造函数模式、原型模式等】


Posted in Javascript onDecember 19, 2018

本文实例总结了JavaScript创建对象方式。分享给大家供大家参考,具体如下:

这里主要是对《JavaScript高级程序设计》第六章(面向对象的程序设计)的总结,书上的这章至少看了4遍是有的。该章主要讲对象的创建与继承。其中创建对象和继承方式至少6种,再加上一些方法属性,很容易搞得晕头转向的。因此有必要对本章的内容理一理,以后忘了也好过来看一看。

由于文章长度的限制,本文主要讲创建对象。

1 创建对象

1.1 一般方法

使用Object或者采用对象字面量的方法。

var o = {a: 1};
var o2=new Object();
o2.a=1;

缺点:使用同一个接口创建很多对象,会产生大量重复的代码。

1.2工厂模式

function parent(name,age){
  var Child = new Object();
  Child.name=name;
  Child.age=age;
  Child.sayHi=function(){
    console.log("Hi");
  }
  return Child;
};
var x = Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

函数parent能够根据接受的参数来构建一个包含所有必要信息的child对象。可以无限次调用这个函数,都会返回一个包含两个属性和一个方法的对象。

解决了创建多个相似对象的问题,但却没有解决对象识别的问题(即怎样知道一个对象的类型)。

1.3构造函数模式

对于构造函数这个名字,学过java或者c++的同学应该都是知道的,在js里也是差不多的。

用构造函数将上面的例子重写如下:

function Parent(name,age){
  this.name=name;
  this.age=age;
  this.sayHi=function(){
    console.log("Hi");
  };
}
var x = new Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

对于构造函数,我们需要在调用的时候加关键字 new。要注意的是,构造函数始终是以一个大写字母开头,而非构造函数始终是以一个小写字母开头。

与工厂模式相比,主要有以下几个不同之处:

  • 没有显示地创建对象;
  • 直接将属性和方法赋给了this对象;
  • 没有return语句。

缺点:使用构造函数的缺点就是每个方法都需要在每个实例上重新创建一遍。

1.4原型模式

我们创建的每一个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性与方法。使用原型对象的好处是可以让所有的对象实例共享其包含的属性与方法。

function Parent(name,age){
  Parent.prototype.name=name;
  Parent.prototype.age=age;
  Parent.prototype.sayHi=function(){
    console.log("Hi");
  };
}
var x = new Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

缺点:优点就是其缺点,方法属性都可以共享。具体可以看下面这个例子

function Parent(name,age){
  Parent.prototype.name=name;
  Parent.prototype.age=age;
  Parent.prototype.arr=["123","we"];
  Parent.prototype.sayHi=function(){
    console.log("Hi");
  };
}
var x = new Parent("Tom",12);
var y = new Parent("Tom1",12);
x.arr.push("x");
y.arr.push("y");
console.log(x.arr);//["123", "we", "x", "y"]
console.log(y.arr);//["123", "we", "x", "y"]

对象x修改自己的属性,竟然会影响到y对象;同理,对y也一样。这个明显就很不合理啊,太可怕了!

1.5组合使用构造函数模式和原型模式

function Parent(name,age){
//只把属性留在这里定义,方法放在原型对象中
  this.name=name;
  this.age=age;
}
//第一种方式
Parent.prototype.sayHi=function(){
  console.log("Hi");
};
//第二种方式
//由于采用对象字面量,因此必须修正其constructor属性;
Parent.prototype={
  constructor:Parent,
  sayHi:function(){
    console.log("Hi");
  }
}
var x = new Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

在这个例子中,实例属性都是在构造函数中定义的,而由所有实例共享的属性constructor和方法则是在原型中定义的。

是目前使用最广泛、认同度最高的一种创建自定义类型的方法。

--------------------------感觉后面几种方法有些变态了--------------------------------

1.6 动态原型模式

function Parent(name,age){
  this.name=name;
  this.age=age;
  if( typeof this.sayHi !="function"){
    Parent.prototype.sayHi=function(){
      console.log("Hi");
    };
  }
}
var x = new Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

先检查某个应该存在方法是否有效再来决定是否需要初始化原型。

1.7寄生构造函数模式

当前面几种都不适用的情况下,可以使用寄生构造函数模式。这种函数的基本思想是创建一个函数,该函数的作用仅仅是封装创建对象的代码,然后再返回新创建的对象。

function parent(name,age){
  var Child = new Object();
  Child.name=name;
  Child.age=age;
  Child.sayHi=function(){
    console.log("Hi");
  }
  return Child;
};
var x = Parent("Tom",12);
console.log(x.name); //Tom
x.sayHi(); //Hi

但是其实就是和工厂模式一模一样,你TM在逗我吗?????

1.8稳妥构造函数模式

稳妥构造函数遵循与寄生构造函数模式类似的模式,但有两点不同:一是新创建对象的实例方法不引用this; 二是不使用new操作调用构造函数。

function Parent(name,age){
  var o=new Object();
 //私有变量或者方法
  var name=name,
    age=age;
  o.sayName=function(){


 //name前面没有this
    console.log(name+" "+age)
  }
  return o;
}
var x = Parent("Tom",12);
x.sayName(); //Tom 12

变量x中保存的是一个稳妥对象,而除了调用sayName()方法外,没有别的方式可以访问其数据成员。

更多关于JavaScript相关内容还可查看本站专题:《javascript面向对象入门教程》、《JavaScript错误与调试技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript数学运算用法总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
jQuery EasyUI API 中文文档 - MenuButton菜单按钮使用介绍
Oct 06 Javascript
基于jquery的滚动条滚动固定div(附演示下载)
Oct 29 Javascript
JQuery Highcharts 动态生成图表的方法
Nov 15 Javascript
js跳转页面方法实现汇总
Feb 11 Javascript
iframe父页面获取子页面参数的方法
Feb 21 Javascript
仿淘宝TAB切换搜索框搜索切换的相关内容
Sep 21 Javascript
使用mouse事件实现简单的鼠标经过特效
Jan 30 Javascript
jQuery获取checkbox选中的值
Jan 28 Javascript
详解Vue2.0之去掉组件click事件的native修饰
Apr 20 Javascript
js实现左右两侧浮动广告
Jul 09 Javascript
JS散列表碰撞处理、开链法、HashTable散列示例
Feb 08 Javascript
如何让微信小程序页面之间的通信不再变困难
Jun 03 Javascript
JavaScript链式调用实例浅析
Dec 19 #Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 #Javascript
如何为vue的项目添加单元测试
Dec 19 #Javascript
浅谈Angular7 项目开发总结
Dec 19 #Javascript
mockjs+vue页面直接展示数据的方法
Dec 19 #Javascript
vue项目搭建以及全家桶的使用详细教程(小结)
Dec 19 #Javascript
vue使用Google地图的实现示例代码
Dec 19 #Javascript
You might like
php使用类继承解决代码重复的问题
2015/02/11 PHP
input+select(multiple) 实现下拉框输入值
2009/05/21 Javascript
javascript中的nextSibling使用陷(da)阱(keng)
2014/05/05 Javascript
简单的jQuery拖拽排序效果的实现(增强动态)
2017/02/09 Javascript
JavaScript基本类型值-Undefined、Null、Boolean
2017/02/23 Javascript
bootstrap timepicker在angular中取值并转化为时间戳
2017/06/13 Javascript
简单实现js拖拽效果
2017/07/25 Javascript
微信小程序 input表单与redio及下拉列表的使用实例
2017/09/20 Javascript
详解vue组件开发脚手架
2018/06/15 Javascript
解决vue-cli单页面手机应用input点击手机端虚拟键盘弹出盖住input问题
2018/08/25 Javascript
从0到1搭建element后台框架优化篇(打包优化)
2019/05/12 Javascript
js实现3D旋转相册
2020/08/02 Javascript
[01:00:10]完美世界DOTA2联赛PWL S2 FTD vs Inki 第二场 11.21
2020/11/24 DOTA
python在多玩图片上下载妹子图的实现代码
2013/08/13 Python
跟老齐学Python之模块的加载
2014/10/24 Python
利用Python画ROC曲线和AUC值计算
2016/09/19 Python
Python 常用 PEP8 编码规范详解
2017/01/22 Python
ubuntu环境下python虚拟环境的安装过程
2018/01/07 Python
Python爬虫使用Selenium+PhantomJS抓取Ajax和动态HTML内容
2018/02/23 Python
[原创]Python入门教程5. 字典基本操作【定义、运算、常用函数】
2018/11/01 Python
Python实现批量修改图片格式和大小的方法【opencv库与PIL库】
2018/12/03 Python
Python cv2 图像自适应灰度直方图均衡化处理方法
2018/12/07 Python
Python编程中flask的简介与简单使用
2018/12/28 Python
python正则表达式匹配不包含某几个字符的字符串方法
2019/07/23 Python
Python如何截图保存的三种方法(小结)
2020/09/01 Python
HTML5的hidden属性兼容老浏览器的方法
2014/04/23 HTML / CSS
澳大利亚实惠时尚女装商店:Katies
2019/06/16 全球购物
医院办公室主任职责
2013/12/29 职场文书
学生会个人自荐书范文
2014/02/12 职场文书
运动会入场词200字
2014/02/15 职场文书
《李时珍夜宿古寺》教学反思
2014/04/09 职场文书
有关西游记的读书笔记
2015/06/25 职场文书
Python还能这么玩之用Python修改了班花的开机密码
2021/06/04 Python
嵌入式Redis服务器在Spring Boot测试中的使用教程
2021/07/21 Redis
Oracle用户管理及赋权
2022/04/24 Oracle
springboot 全局异常处理和统一响应对象的处理方式
2022/06/28 Java/Android