从“原型”和“新”转向封闭和暴露模式

2023-12-14

我一直在重构别人的 JavaScript 代码。

BEFORE:

function SomeObj(flag) {
    var _private = true;
    this.flag = (flag) ? true : false;
    this.version="1.1 (prototype)";
    if (!this._someProperty) this._init();
            // leading underscore hints at what should be a 'private' to me
    this.reset(); // assumes reset has been added...
}

SomeObj.prototype.reset = function() {
    /* perform some actions */
}

/* UPDATE */
SomeObj.prototype.getPrivate = function() {
    return _private; // will return undefined
}

/* ...several other functions appended via `prototype`...*/

AFTER:

var SomeObj = function (flag) {
    var _private = true;
    this.flag = (flag) ? true : false;
    this.version = "2.0 (constructor)";

    this.reset = function () {
       /* perform some actions */
    };

    /* UPDATE */
    this.getPrivate = function() {
        return _private; // will return true
    }

    /* other functions and function calls here */
}

对我来说,第一个示例看起来很难阅读,尤其是在更大的上下文中。添加方法如reset像这样,使用prototype属性,似乎不太受控制,因为它可能发生在脚本中的任何地方。我的重构代码(上面的第二个示例)对我来说看起来更加整洁,因此更易于阅读,因为它是独立的。我通过变量声明获得了一些隐私,但失去了原型链的可能性。

...

问题:

  1. 首先,我有兴趣知道我还因上述内容而失去了什么prototype,或者原型链的丢失是否会产生更大的影响。本文已经 6 岁了,但声称使用prototype在大规模上,属性比封闭模式更有效。

  2. 上面的两个例子仍然会被实例化new操作员;他们都是“经典”的构造函数。最终我什至想从这个模型转移到一个模型,其中所有属性和函数都声明为var我有一个公开的方法,它能够返回一个对象,打开我需要的所有属性和方法,对私有者拥有特权(通过封闭)。像这样的东西:

    var SomeObj = (function () {
    
        /* all the stuff mentioned above, declared as 'private' `var`s */
    
        /* UPDATE */
        var getPrivate = function () {
            return private;
        }
    
        var expose = function (flag) {
             // just returns `flag` for now
             // but could expose other properties
             return {
                 flag: flag || false, // flag from argument, or default value
                 getPrivate: getPrivate
             } 
        };
    
        return {
            expose: expose
        }
    })(); // IIFE
    
    // instead of having to write `var whatever = new SomeObj(true);` use...
    var whatever = SomeObj.expose();
    

    StackOverflow 上有一些关于“原型与闭包”问题的答案(here and here, 例如)。但是,正如prototype财产,我感兴趣的是朝着这个方向以及远离new运算符意味着我的代码的效率和任何可能性的损失(例如instanceof丢失了)。如果我无论如何都不打算使用原型继承,那么我实际上会失去任何东西吗?new操作员?

  3. 鉴于我要求提供上述细节,如果允许的话,这是一个更宽松的问题:如果prototype and new确实是最有效的方法,比闭包具有更多优势(无论您认为它们可能是什么),是否有任何指南或设计模式可以以更简洁的方式编写它们?

...

UPDATE:

注意expose每次都会返回一个新对象,因此这就是实例化发生的地方。据我了解,该对象指的是在SomeObj闭包,它们在所有对象中都是相同的方法(除非被覆盖)。在这种情况下flag变量(我现在已经更正了),这可以从参数继承expose,有一个默认值,或者再次引用封装的预先存在的方法或属性。因此,存在正在生成的对象的实例,并且这里发生了一些继承(加上多态性?)。

因此,重复问题 2:如果我无论如何都不打算使用原型继承,那么我实际上会失去前面提到的任何东西吗?new操作员?

非常感谢到目前为止的回答,这有助于澄清我的问题。


根据我的经验,不使用你唯一失去的东西.prototype是内存 - 每个对象最终都拥有自己的其中定义的函数对象的副本。

如果您只想实例化“少量”对象,这可能不是一个大问题。

关于您的具体问题:

  1. 该链接文章的第二条评论非常相关。作者的基准是错误的 - 它正在测试运行构造函数的开销also声明四个内部函数。它是not测试这些功能的后续性能。

  2. 您的“关闭和公开”代码示例不是面向对象的,它只是带有一些封闭的私有变量的名称空间。由于它不使用new如果您希望从中实例化对象,那么它是没有用的。

  3. 我无法回答这个问题——“视情况而定”是你能得到的最好的答案。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从“原型”和“新”转向封闭和暴露模式 的相关文章

  • 浏览器安全错误:“由于安全违规,此页面无法显示”[关闭]

    Closed 这个问题是无法重现或由拼写错误引起 help closed questions 目前不接受答案 我在一家网络开发公司工作 我为我们的一些营销人员设计了一个页面 以便将自定义页脚添加到我们应用程序中的各个页面 在部署我们的产品供
  • 克隆表行

    我怎样才能使用javascript 我假设 来克隆一个表格行 就像下图所示的那样 您可以将现场活动连接到所有按钮 例如 如果您给他们一类克隆 则以下内容将起作用 input clone live click function put jqu
  • 用玩笑模拟高阶组件

    我想确保 HOC 组件被开玩笑地调用 但我似乎无法理解jest mock上班 我的 HOC 是这样的 const withEntity args gt const wrappedComponent WrappedComponent gt c
  • Javascript 字符串/整数比较

    我在 HTML 中存储一些客户端参数 然后需要将它们作为整数进行比较 不幸的是我遇到了一个我无法解释的严重错误 该错误似乎是我的 JS 将参数读取为字符串而不是整数 导致我的整数比较失败 我生成了一个错误的小例子 我也无法解释 运行时以下返
  • 客户端 GitHub 身份验证

    我正在使用 Javascript 对 GitHub 进行基本身份验证 例如 以下 shell 命令从 Github 获取令牌 curl i u uaername password k d scopes repo https api gith
  • 如何使用 html 标签包装 window.getSelection().getRangeAt(0) 中的文本选择?

    如何从 window getSelection getRangeAt 0 中进行选择并用 HTML 标签 例如 span 或 mark 包围它 我更喜欢直接的 javascript 或 jQuery 解决方案 我可以使用警报输出选定的文本
  • 获取访客的 Optimizely A/B 测试和变化

    当我在网站上运行实验时 我希望能够找出当前访问者看到的测试和变体 我无法找到如何做到这一点优化Javascript API https www optimizely com docs api 您可以获得第一个正在运行的实验的 ID 假设您有
  • 将新数据添加到 d3 Streamgraph 时的转换

    我使用d3绘制了一个与官方示例非常相似的流图http bl ocks org mbostock 4060954 http bl ocks org mbostock 4060954 唯一的区别是我如何用新数据更新它 我不仅想要垂直 y 值 过
  • 在 json 对象中执行 javascript 代码?

    有远吗 所以像这样 key1 val1 key2 val2 some code document getElementById someid innerHTML test 那么 some code 会在没有任何用户干预的情况下执行吗 No
  • 发送带有图像的嵌套 JSON

    我一直在尝试研究一种能够通过 Ajax 将嵌套 JSON 请求发送回服务器的方法 根据我的理解 我们主要用于向服务器发送图像或文件的 formdata 在这种情况下不起作用 因为 FormData 似乎不处理嵌套对象 这就是我需要发送的有效
  • 在 Bootstrap 选择器上使用 jQuery 取消选择选项

    我对一些 UI 元素使用 Bootstrap SelectPicker 它允许用户选择多个选项并将其呈现在段落标签中的屏幕上 他们还应该能够删除选定的选项 这是我的代码 用于将选定的选项渲染到屏幕上 以便每个选项旁边都会显示一个 X 单击它
  • JQuery mouseover 函数多次触发

    我很长时间以来一直使用这种方法来为整个类 按钮等 设置事件 div bigButton mouseover function this style backgroundColor dfdfdf 然而 在进行一些测试时 我刚刚注意到 当将鼠标
  • 解析字符串:提取单词和短语 [JavaScript]

    我需要在以空格分隔的术语列表中支持确切的短语 用引号引起来 因此 用空格字符分割相应的字符串已经不够了 Example input foo bar lorem ipsum baz output foo bar lorem ipsum baz
  • Lighthouse 多个 URL

    我需要对一个网站进行全面审核 但我想知道是否有任何方法可以让 Lighthouse 做到这一点 我知道他们不支持完整的站点审核或多个 URL 但我发现可以使用 bash 脚本来完成 因此 我将不胜感激对此案的任何帮助 或者您可能会推荐任何灯
  • 尝试将远程图像转换为 Base64 数据时出现 CORS 错误[重复]

    这个问题在这里已经有答案了 我需要将远程图像转换为给定其 URL 的 base64 但我遇到了 CORS 错误 并且不确定如何解决 我遵循了这个问题的一些解决方案 如何使用javascript将图像转换为base64字符串 https st
  • 从组件刷新/重新加载 ember 路由

    我有一个组件 它实际上是一个模式对话框 当我完成该对话框并按 确定 按钮时 我想留在打开该对话框的停留页面上 这并不难 但问题是该对话框更改了数据 我通过 REST 调用获取数据 因此我需要刷新已经所在的路线以反映数据更改 因为我是从组件中
  • execCommand 的替代品

    我希望创建一个所见即所得编辑器 使用 jQuery 作为框架 我可以使用不同的方法来简化生产 我现在确实有一个正在工作的编辑 而且运作良好 我使用 iFrame 并将其设计模式设置为打开并从那里开始 然而 有一些事情困扰着我 以更改所选文本
  • 将json数据从servlet传递到jsp到js文件

    我得到了这个创建 JSON 数据的 servlet 我想将此数据传递到一个 jsp 页面 该页面应该通过 InfoVis 工具包显示数据 servlet java JSONObject json new JSONObject JSONArr
  • 如何使用 jQuery 解析 JavaScript 对象

    jQuery JavaScript 中用于解析 JSON 对象并返回键 值对的 foreach 等效项是什么 JSON 对象 是什么意思 JSON 是一种用于序列化对象的文本格式 如果要循环访问通过反序列化 JSON 字符串获得的对象中的属
  • ASP.NET MVC3 Ajax.ActionLink - 条件确认对话框

    我有一个 Ajax ActionLink 仅当满足某些条件 用户有未保存的更改 时 我才希望显示一个确认对话框 我创建了一个 JavaScript 函数 它根据需要显示确认对话框 并根据响应返回 true 或 false 我将其绑定到 Ac

随机推荐

  • 身份验证失败 - 999 - HTTP 状态代码未处理或不允许

    I using scrapy 我想得到忽略响应 URL 我只是在输出控制台中看到 调试 忽略响应 https www mywebsite com gt HTTP 状态代码未处理或不允许 根据文档here您可以添加应该由蜘蛛处理的 HTTP
  • 似乎无法通过 cURL 获取网页内容 - 用户代理和 HTTP 标头均已设置?

    由于某种原因 我似乎无法通过 cURL 获取此特定网页的内容 我已经设法使用 cURL 很好地访问 顶级页面 内容 但相同的自建快速 cURL 功能似乎不适用于链接的子网页之一 顶级页面 http www deindeal ch 子页面 h
  • C++ - stringstream <<“覆盖”

    我正在用 C 制作 OpenGL 游戏 与其他语言相比 我对 C 相当缺乏经验 不管怎样 我为一些图像创建了一个带有 base 目录的字符串流 然后我将此字符串流作为函数参数传递给构造函数 构造函数附加图像文件名 然后尝试加载结果路径 然而
  • 用 NodeJS 编写的简单 TCP 服务器中的 socket.emit?

    正如你将看到的 我不太了解 TCP 服务器和客户端的基本概念 可能 socket emit 甚至不可能 但我想知道最好的替代方案或类似的东西 Socket io 有一个漂亮的东西可以发出事件并在另一端捕获它们 它位于它的首页 http so
  • Azure Function:部署后旧代码仍在运行

    现在 我再次面临这样的问题 即使通过 KUDU 的 zip 部署返回成功后 旧代码仍在 Azure Function App 上使用 当然 我预计新代码会在大约 30 分钟后加载 而不是立即加载 问题被标记为关闭 在这种情况下 最佳实践是什
  • 二维叉积定义

    In 判断线段是否在多边形内部我注意到接受的答案有一个不寻常的二维叉积定义 u1 u2 x v1 v2 u1 v2 u2 v1 我从未遇到过像这样的二维叉积的定义 谁能告诉我这个定义的出处 不是数学专家 但交叉积ND被定义为操作N 1向量产
  • 零大小数组分配的作用/含义是什么?

    查看一些示例代码并遇到一些零大小数组分配 我创建了以下代码片段来澄清我的问题 这是有效的代码 class T int main void T ptr new T 0 return 0 它有什么用 ptr 有效吗 这个结构可移植吗 C 标准中
  • 限制 NSArray 中的重复条目

    我有一个数组 其中包含一些重复的条目 首先 有什么办法可以限制插入数据时的重复条目吗 其次 如果一个数组已经具有比其他方式重复的值 我们只能从该数组中检索唯一的值 我听说过 NSSet 但我不知道如何使用它 不要使用 NSSet 您只能在创
  • 卡夫卡流 RoundRobinPartitioner

    我编写了一个kafka流代码 使用kafka 2 4 kafka客户端版本和kafka 2 2服务器版本 我的主题和内部主题有 50 个分区 我的 kafka 流代码具有 selectKey DSL 操作 并且我有 200 万条使用相同 K
  • 如何检查一个 div 是否包含另一个 div?

    如果我的父 div 有一个仅使用 JavaScript 的子 div 我需要显示警报 而不使用 jQuery 我尝试过使用contains 函数来检查我的 div 并发送警报 但它不起作用 div class ro div
  • 如何在c#中将数据表绑定到datagridview

    我需要绑定我的数据表 to my 数据网格视图 我这样做 DTable new DataTable SBind new BindingSource ServersTable DataGridView for int i 0 i lt Ser
  • 在数组上的过滤方法之后指定所需的类型

    我想在两个数组之间进行分离 在一个数组中 对象没有特定的值 另一方面 它应该有一个字符串 interface Relation
  • NodeList 上的 addEventListener [重复]

    这个问题在这里已经有答案了 NodeList是否支持addEventListener 如果不是 将 EventListener 添加到 NodeList 的所有节点的最佳方法是什么 目前我正在使用如下所示的代码片段 是否有更好的方法来做到这
  • mysql:获取两个日期时间之间的记录计数

    我在 MySQL 中遇到了一个问题 我想获取两个日期时间条目之间的记录数 例如 我的表中有一个名为 created 的列 其中包含datetime数据类型 我想计算在 今天凌晨 4 30 和 当前日期时间 之间创建的日期时间记录 我尝试了
  • 如何在多线程中取消DefaultHttpClient执行过程

    我正在开发一个非常依赖互联网的Android应用程序 我经常使用它检索数据RestClient类 其中包含有关使用 DefaultHttpClient 执行网络请求的一些详细信息 我总是使用不同的线程来执行 HTTP 请求 我创建一个这样的
  • 如何解决C和Python混合编程时的“分段错误”?

    在我的Ubuntu下 猫测试 py Filename test py def Hello print Hello world 猫汤姆 cpp include
  • CSS中如何让文本围绕不规则形状流动

    我正在尝试弄清楚如何让文本围绕页面上的不规则形状流动 但我不太幸运地弄清楚如何做我想做的事情 我附上了一张显示我正在尝试使用的布局的图像 我希望文本像图像中那样流畅 我在 MS Paint 中做了这个模型 每个页面上都可以有任何内容 所以我
  • 如何使我的 Blazor 服务器端应用程序 IIS 8.5 保持活动状态

    我需要让我的 blazor 服务器端应用程序始终保持活动状态 我尝试将 iis 8 5 启动模式设置设置为 alwaysrunning 并将 idle 设置为 0 但仍然关闭应用程序并捕获停止信号 在 23 点到 29 点之间 我必须做什么
  • 使用从kernel32.dll导入的SetThreadAffinityMask函数

    我正在尝试使用设置线程亲和力SetThreadAffinityMask在我的 C 代码中从 kernel32 dll 导入的函数 这就是我导入它的方式 DllImport kernel32 dll static extern IntPtr
  • 从“原型”和“新”转向封闭和暴露模式

    我一直在重构别人的 JavaScript 代码 BEFORE function SomeObj flag var private true this flag flag true false this version 1 1 prototy