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 相关文章推荐
css transform 3D幻灯片特效实现步骤解读
Mar 27 Javascript
一个非常全面的javascript URL解析函数和分段URL解析方法
Apr 12 Javascript
js运动动画的八个知识点
Mar 12 Javascript
jQuery如何使用自动触发事件trigger
Nov 29 Javascript
4种JavaScript实现简单tab选项卡切换的方法
Jan 06 Javascript
AngularJs  Using $location详解及示例代码
Sep 02 Javascript
Vue-Router实现组件间跳转的三种方法
Nov 07 Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
Apr 26 Javascript
vue-cli构建项目下使用微信分享功能
May 28 Javascript
Ajax请求时无法重定向的问题解决代码详解
Jun 21 Javascript
基于layui实现高级搜索(筛选)功能
Jul 26 Javascript
JavaScript设计模式--简单工厂模式实例分析【XHR工厂案例】
May 23 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
一个分页的论坛
2006/10/09 PHP
解决thinkPHP 5 nginx 部署时,只跳转首页的问题
2019/10/16 PHP
js模拟弹出效果代码修正版
2008/08/07 Javascript
Javascript 跨域访问解决方案
2009/02/14 Javascript
利用JS实现浏览器的title闪烁
2013/07/08 Javascript
Document:getElementsByName()使用方法及示例
2013/10/28 Javascript
Jquery ajax执行顺序 返回自定义错误信息(实例讲解)
2013/11/06 Javascript
jquery 操作css样式、位置、尺寸方法汇总
2014/11/28 Javascript
Node.js中child_process实现多进程
2015/02/03 Javascript
JavaScript通过字典进行字符串翻译转换的方法
2015/03/19 Javascript
AngularJS directive返回对象属性详解
2016/03/28 Javascript
判断数组是否包含某个元素的js函数实现方法
2016/05/19 Javascript
jQuery  ready方法实现原理详解
2016/10/19 Javascript
微信小程序之ES6与事项助手的功能实现
2016/11/30 Javascript
微信小程序Server端环境配置详解(SSL, Nginx HTTPS,TLS 1.2 升级)
2017/01/12 Javascript
Angular 4 指令快速入门教程
2017/06/07 Javascript
vue实现固定位置显示功能
2019/05/30 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
[37:35]DOTA2上海特级锦标赛A组资格赛#1 Secret VS MVP.Phx第二局
2016/02/25 DOTA
让python的Cookie.py模块支持冒号做key的方法
2010/12/28 Python
在Python下利用OpenCV来旋转图像的教程
2015/04/16 Python
常用python编程模板汇总
2016/02/12 Python
Python实现PS滤镜特效之扇形变换效果示例
2018/01/26 Python
Python 批量合并多个txt文件的实例讲解
2018/05/08 Python
python实现将文件夹下面的不是以py文件结尾的文件都过滤掉的方法
2018/10/21 Python
Python matplotlib绘制饼状图功能示例
2019/09/10 Python
python3爬虫中异步协程的用法
2020/07/10 Python
如何在pycharm中安装第三方包
2020/10/27 Python
项目资料员岗位职责
2013/12/10 职场文书
幼儿园实习自我鉴定
2013/12/15 职场文书
管理学院毕业生自荐信范文
2014/03/10 职场文书
爱国演讲稿400字
2014/05/07 职场文书
新教师个人工作总结
2015/02/06 职场文书
浅谈Python3中datetime不同时区转换介绍与踩坑
2021/08/02 Python
解决MySQL报“too many connections“错误
2022/04/19 MySQL
go goth封装第三方认证库示例详解
2022/08/14 Golang