工厂函数和构造函数的区别

2023-11-12

工厂函数和构造函数的区别

下面是给出的两个都是实现 “定义使用值的范围” 的函数, 第一个工厂函数(工厂模式)用以创建并初始化类的实例,而且给出了一个表示“值的范围”的类定义了原型对象;第二个是使用构造函数代替工厂函数来实现相同功能的代码段 。

下面是“inherit()通用写法

function inherit(d){
	  if(d == null) throw TypeError(); //d 是一个对象,但不能是null;
	    if(Object.create)                //如果Object.create()存在
	        return Object.create(d);    //直接使用d
	    var t = typeof d;               //否则进行进一步检测
	    if(t !== 'object' && t !== 'function') throw TypeError();
	    function f(){};                 //定义一个空的构造函数
	    f.prototype = d;                //将其原型属性设置为 d;
	    return new f();                 //使用f()创建d的继承对象
}

下面是“工厂函数”的一段代码

function range(from,to){
    //使用inherit()函数创建对象,这个对象继承自在下面定义的原型对象
    //原型对象作为函数的一个属性存储,并定义所有“范围对象”所共享的方法。
    var r = inherit(range.methods);

    //存储新的“范围对象”的起始位置和结束位置
    //这两个属性是不可继承的,每个对象都拥有唯一的属性。
    r.from = from; 
    r.to =to;
    return r;//返回这个新建立的对象
}

//原型对象定义方法,这些方法为每个范围对象所继承
range.methods = {
    includes: function(x){ //如果x在范围内,返回 true 否则返回false
         if(this.from <= x && x <= this.to){
             return x;
         }

        return x;
    },

    foreach: function(f){ //对范围内的每个整数都调用一次 f
        for(var x = Math.ceil(this.from);x <= this.to; x++) 
             f(x);
    },

    toString: function(){
        return "("+this.from +".."+ this.to + ")";
    }
};

var r = range(1,4); 
r.foreach(console.log); // 输出 1 2 3 4
console.log(r.toString()); // 输出(1..4)
r.includes(2);          //返回2

这段代码是用来定义一个工厂方法 range(),用来创建新的范围对象。 rang()函数定义了一个属性range.methods,用来快捷地存放定义类的原型对象。把原型对象挂在函数上不是惯用做法。而且range()函数给每个范围对象都定义了from 和to 属性,用来定义范围的起始位置和结束位置,这两个属性是非共享的,也不可继承。

使用构造函数代替“工厂函数”

	function Range(from, to){  //构造函数初始化
	    this.from = from;
	    this.to = to;
	}

Range.prototype = {   //所有范围对象都继承自这个对象
    includes: function(x){
        return this.from <= x && this.to >= x;
    },
    foreach: function(f){
        for(var x = Math.ceil(this.from); x <= this.to; x++)
            f(x)
    },
    toString: function(x){
        return "(" + this.from + ".." + this.to + ')';
    }
};

var t = range(1,4);
t.foreach(console.log); // 输出 1 2 3 4
console.log(t.toString());// 输出 (1..4);
t.includes(3);             // 输出 3

上述两个函数的不同之处

Range()构造函数 range()工厂函数
通过new关键字调用,不必调用inherit() 不需要使用new,但是需要调用inherit()
使用构造函数调用创建对象 调用普通函数创建对象
通过this关键字获取这个新对象,不必返回新对象。 函数需要返回新建立的对象
构造函数会自动创建对象,然后将构造函数作为这个对象的方法来调用一次,最后返回这个新对象 函数里面的属性是不可继承的,每个对象的属性都拥有唯一的属性
原型对象的命名Range.prototype是强制的命名,对该函数的调用会自动使用Range.prototype作为新Range对象的原型 原型是range.methods,这种命名方式方便且具有很好的语义,担又过于随意。
Range()构造函数与range()工厂函数的相同之处
两者的范围方法定义和调用方式是完全一样的
2、构造函数是用来初始化新创建的对象的。

使用关键字new来调用构造函数会自动创建一个新的对象,因此构造函数本身只需初始化这个新对象的状态即可。
调用构造函数的一个重要的特征: 构造函数的prototype属性被用作新对象的原型。这意味着通过一个构造函数创建的所有对象都继承自一个相同的对象,因此他们都是同一个类的成员。

3、构造函数的内部原理、

1、在函数体最前面隐式的加上this = {}
2、执行this.xxx = xxx;
3、隐式的返回 this

4、在用new操作符创造实例时,会经历如下4个阶段:

  1. 创建一个新对象,此时该对象为空对象。
  2. 将构造函数的作用域赋给这个空对象(因此构造函数中的this就指向了该空对象)
  3. 执行构造函数内的代码(由于this指向了该空对象,此步骤为新对象添加属性)
  4. 返回新对象(这里针对构造函数没有返回值或返回值为基本类型时。如果构造函数内有引用类型的返回值,那么该返回值会替代第一步创建的对象作为构造函数的返回值。)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

工厂函数和构造函数的区别 的相关文章

  • 爬虫实战之《流浪地球》豆瓣影评分析(一)

    背景与挖掘目标 获取豆瓣评论数据 分析好评与差评的关键信息 分析评论数量及评分与时间的关系 分析评论者的城市分布情况 1 背景与挖掘目标 豆瓣 douban 是一个社区网站 网站由杨勃 网名 阿北 创立于2005年3月6日 该网站以书影音起
  • ChatGPT漫谈(二)

    ChatGPT 脱胎 于OpenAI在2020年发布的GPT 3 任何外行都可以使用GPT 3 在几分钟内提供示例 并获得所需的文本输出 GPT 3被认为是当时最强大的语言模型 但现在 ChatGPT模型似乎更强大 ChatGPT能进行天马
  • VUE 自定义 穿梭框

    某次项目要使用穿梭框进行数据选择 项目使用的element ui框架 框架中的穿梭框是这样子的 好像不能满足我的需求 因为需要展示很多内容 包括图片等信息 也要加上很多样式等等 我尝试这去改造 一会后觉得还是自己动手去写一个靠谱 几经鼓捣效
  • [华为云云服务器评测] 华为云耀云服务器 Java、node环境配置

    系列文章目录 第一章 linux实战 华为云耀云服务器L实例 Java node环境配置 文章目录 系列文章目录 前言 一 任务拆解 二 修改密码 三 配置安全规则 四 远程登录并更新apt 五 安装 配置JDK环境 5 1 安装openj

随机推荐

  • 数据结构和简单算法思想

    只为自己学习进行一下记录 虽然之前上了一些关于数据结构 算法之类的课 但之前都没有怎么搞懂 尤其是算法里面的一些算法思想 现在看能不能补上 就是一些大佬的算法指导 刷LeetCode的一些题 回看之前的书上面的重点 教材是清华大学出版社的数
  • IDEA vs VSCode在java开发上的横向对比

    讲讲出身 了解一个人需要了解他的出身 一个app也是如此 Visual Studio Code 简称 VS Code 是Microsoft在2015年4月30日Build开发者大会上正式宣布一个运行于 Mac OS X Windows和 L
  • java文件操作报错:java.io.FileNotFoundException:D:\..(拒绝访问)

    import java io Description 复制文件 从一个输入流中读取数据 然后通过输出流写入目标位置 一边读一边写 ClassName CopyFile Version V1 0 public class CopyFile p
  • softmax回归

    softmax回归 线性回归不同 softmax回归的输出单元从 个变成了多个 且引 了softmax运算使输出更适合离散值的预测和训练 softmax回归跟线性回归 样将输 特征与权重做线性叠加 它将logistic 激活函数推广到C类
  • 面向对象:类的概念和定义!

    面向对象的概念 对象 Object 含有 物体 的概念 一切皆物体 对象 对象由静态的属性和动态的行为组成 属性 行为 存储 保温 类 一组具有相同属性和行为的对象的抽象 杯子 车 不管白猫黑猫 抓到老鼠就是好猫 这句话中存在两个对象 白猫
  • Kubernetes调度器介绍

    特邀文章 原载于Gemini Open Cloud的博客 作者是Gemini Open Cloud的CEO Patrick Fu Kubernetes是一个可移植的 可扩展的 开源的集群管理器 用于管理容器化工作负载和服务 Kubernet
  • Jumperserver堡垒机管理服务器实战

    一 Jumpserver堡垒机简介 1 跳板机简介 跳板机就是一台服务器 开发或运维人员在维护过程中首先要统一登录到这台服务器 然后再登录到目标设备进行维护和操作 跳板机缺点 没有实现对运维人员操作行为的控制和审计 使用跳板机的过程中还是会
  • 智能家居之设备配网(理论篇)

    前言 记录杭州疫情 独自在杭州跨年了 不过也可以抽出点时间来写写博客分享一下 在这也要祝大家虎年大吉 本篇目标 介绍当前智能家居产品中 关于设备配网中用到的一些技术 配网的作用 现在家庭生活中 智能设备越来越多 大到手机 电脑 小到插座 灯
  • windows子系统wsl_您(或我)不知道的Cool WSL(Linux的Windows子系统)提示和技巧

    windows子系统wsl It s no secret I dig WSL Windows Subsystem for Linux and now that WSL2 is available in Windows Insiders Sl
  • 4.4.1 英文标点符号验证

    英文标点符号比较多 如 逗号 点号 问号 冒号 分号 单引号 感叹号 双引号 连接号 破折号 省略号 小括号 中括号 大括号 所有格符号 等 以下正则表达式能够验证英文标点符号 2 3 63 正则表达式 63 解释 可以匹配 2 匹配破折号
  • feign获取outstream_spring cloud——feign为GET请求时的对象参数传递

    一 问题重现 楼主在使用feign进行声明式服务调用的时候发现 当GET请求为多参数时 为方便改用DTO对象进行参数传递 但是 在接口调用时feign会抛出一个405的请求方式错误 timestamp 1540713334390 statu
  • ubuntu上编译fortran_Ubuntu下安装Intel Fortran编译器(ifort)

    Intel Fortan Compiler简称ifort Windows下的ifort是收费的 但是Linux系统下提供免费的ifort 可以在下面的链接中下载需要的版本 必须先注册 随后会收到官网发来的邮件 里面提供了接下来安装需要的se
  • logging level级别

    日志记录器 Logger 是日志处理的核心组件 log4j具有5种正常级别 Level 1 static Level DEBUG DEBUG Level指出细粒度信息事件对调试应用程序是非常有帮助的 一般认为比较重要的方法执行需要详细查看运
  • make 及 make clean 的作用

    在编译源代码安装软件时 很熟悉的步骤是 make 及 make install 例如 configure make make install 以下是 make 及 make clean 的分别 make 一般上 make 是 make al
  • Windows安装Neo4j

    图数据库概述 图数据库是基于图论实现的一种NoSQL数据库 其数据存储结构和数据查询方式都是以图论 它以图为研究对象图论中的图是由若干给定的点及连接两点的线所构成的图形 为基础的 图数据库主要用于存储更多的连接数据 Neo4j说明 Neo4
  • ifconfig: command not found

    说明 新装的Linux在执行ifconfig查看ip时会报ifconfig command not found 表示未安装ifconfig命令 此处可使用ip addr查看ip 可查看是否安装了ifconfig命令 解决 ifconfig
  • TCP中的Nagle算法

    一 Nagel算法 TCP IP协议中 无论发送多少数据 总是要在数据前面加上协议头 同时 对方接受到数据 也需要发送ack表示确认 为了尽可能利用网络带宽 TCP总是希望尽可能发送足够大的数据 在一个连接中会设置MSS参数 因此 TCP
  • Google Cloud Spanner和Cloud Bigtable最新更新

    Google云平台提供了各种云原生数据库服务 最近 Google更新了其中的两项服务 这些更新会影响Cloud Spanner数据库服务 一种的托管关系数据库产品 和Cloud Bigtable 一种托管的NoSQL键值和宽列数据库 几家领
  • P1020 [NOIP1999 普及组] 导弹拦截

    题目 题目链接 题解 看了网上好多讲解的博客 都好屑啊 就当已知第一问求解最长不上升子序列长度 第二问求解最长上升子序列长度 如果想知道证明 可以自行百度Dilworth定理 或者参考这个博客 未优化 O n2 未优化的比较基础 第一问 状
  • 工厂函数和构造函数的区别

    工厂函数和构造函数的区别 下面是给出的两个都是实现 定义使用值的范围 的函数 第一个工厂函数 工厂模式 用以创建并初始化类的实例 而且给出了一个表示 值的范围 的类定义了原型对象 第二个是使用构造函数代替工厂函数来实现相同功能的代码段 下面