草庐IT

javascript - 在 Javascript 中强制执行私有(private)方法是个好主意吗?

coder 2024-05-13 原文

我正在与一位开发人员讨论侵入 javascript 私有(private)函数是否有意义。

备选方案是:

  1. 一个构造函数和一个包含所有函数的原型(prototype),非 API 方法(私有(private))将仅使用下划线 _function_name 命名,以便开发人员知道他们可以调用什么,不能调用什么。
  2. API 函数的构造函数和原型(prototype),以及在私有(private)命名空间内作为私有(private)函数的自由函数,除了这个命名空间之外,其他命名空间都隐藏了它们。

我们不考虑其他方法,例如在 var private_var= function(){} 形式的构造函数中创建私有(private)函数,因为每次对象获取时都会触发所有这些函数的创建实例化,每个对象都有自己的集合。

我们为他们准备的理由:

1

  • Javascript 本身不支持私有(private)函数,实际上没有私有(private)/ protected /公共(public)可见性的概念,所以这基本上是一种 hack
  • 在方法名中使用下划线清楚地标记给定类/原型(prototype)的边界是什么,没有必要“强制”它,事实上像 Python 这样的语言没有私有(private)方法而且 python 用户似乎从来不关心关于它除了使用下划线
  • 即使 private 得到强制执行,对于一种您可以动态替换公共(public)方法的语言,它有什么意义?
  • 影响可读性,很多,私有(private)函数被分隔到另一组大括号中作为它们的作用域,它们不能使用 this 或者它们需要用 function.call(object) 调用function.apply(object)

2

  • 通过封装远离类/原型(prototype)用户手的私有(private)方法带来明确的限制
  • 它或多或少是行业标准,许多 javascript 开发人员都这样使用它

我们怀疑,因为很多开发人员都在使用它,所以可能还有其他原因,比如性能等原因。

由于我们对 Javascript 的了解非常有限,我们决定将其发布在 stackoverflow 中以了解哪种方法更好以及原因。

最佳答案

您将如何侵入 javascript 私有(private)函数以及出于什么目的?

我认为创建类、私有(private)函数等的不同方法取决于您的动机。

当您尝试进行单元测试并且您真的想分解从外部看起来像是一个巨大的方法时,下划线约定会有所帮助。

我觉得在其他所有情况下,您都应该尝试使事情真正私密。如果你想公开一个漂亮、干净的 API 供其他人使用,他们应该不需要看到幕后的内容。为什么要曝光?这导致了关于私有(private)和公共(public)的一般 session :Why "private" methods in the object oriented?

您确实有一些私有(private)化方法的选择,其中一些选择会影响性能。

下划线约定:

function Pizza() {
   this._pepperoni = function () {};
}

function Pizza() {
}

Pizza.prototype._pepperoni = function () {};

范围界定

function Pizza() {
    function pepperoni() {};
}

命名空间/模块

var pizza = pizza || {};
(function() {
    function pepperoni() {};
    function create() {
        pepperoni();
    }
    window.pizza.create = create; // or module.export = pizza or both
}());

模块模式

(function(){
    function pepperoni() {};
    function Pizza() {
        pepperoni();
    }

    window.Pizza = Pizza;
}());

关于重新创建您的函数与一次定义它们。首先,如果您想使用内部私有(private)成员并仍然使用“this”,只需创建一个名为 self 的新变量并将 this 分配给它:

function Pizza() {
    var self = this;
    function pep() {
       self.x = 1;
    }
}

接下来,我尝试测试重新定义和预先编写函数之间的性能差异:http://jsperf.com/private-methods我认为每次都重新创建您的函数,它可以为您节省不到 20% 的操作/秒。

我不推荐任何方法,它们在不同时间都是有效且有用的。有时更多是关于语义,有时是关于性能,有时是为了满足某些目的,比如单元测试。

关于javascript - 在 Javascript 中强制执行私有(private)方法是个好主意吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12903706/

有关javascript - 在 Javascript 中强制执行私有(private)方法是个好主意吗?的更多相关文章

  1. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  2. ruby-openid:执行发现时未设置@socket - 2

    我在使用omniauth/openid时遇到了一些麻烦。在尝试进行身份验证时,我在日志中发现了这一点:OpenID::FetchingError:Errorfetchinghttps://www.google.com/accounts/o8/.well-known/host-meta?hd=profiles.google.com%2Fmy_username:undefinedmethod`io'fornil:NilClass重要的是undefinedmethodio'fornil:NilClass来自openid/fetchers.rb,在下面的代码片段中:moduleNetclass

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  4. ruby - Chef 执行非顺序配方 - 2

    我遵循了教程http://gettingstartedwithchef.com/,第1章。我的运行list是"run_list":["recipe[apt]","recipe[phpap]"]我的phpapRecipe默认Recipeinclude_recipe"apache2"include_recipe"build-essential"include_recipe"openssl"include_recipe"mysql::client"include_recipe"mysql::server"include_recipe"php"include_recipe"php::modul

  5. ruby - 为什么 Ruby 的 each 迭代器先执行? - 2

    我在用Ruby执行简单任务时遇到了一件奇怪的事情。我只想用每个方法迭代字母表,但迭代在执行中先进行:alfawit=("a".."z")puts"That'sanalphabet:\n\n#{alfawit.each{|litera|putslitera}}"这段代码的结果是:(缩写)abc⋮xyzThat'sanalphabet:a..z知道为什么它会这样工作或者我做错了什么吗?提前致谢。 最佳答案 因为您的each调用被插入到在固定字符串之前执行的字符串文字中。此外,each返回一个Enumerable,实际上您甚至打印它。试试

  6. 通过 MacPorts 的 RubyGems 是个好主意吗? - 2

    从MB升级到新的MBP后,Apple的迁移助手没有移动我的gem。我这次是通过macports安装ruby​​gems,希望在下次升级时避免这种情况。有什么我应该注意的陷阱吗? 最佳答案 如果你想把你的gems安装在你的主目录中(在传输过程中应该复制过来,作为一个附带的好处,会让你以你自己的身份运行geminstall,而不是root),将gemhome:键设置为您在~/.gemrc中的主目录中的路径. 关于通过MacPorts的RubyGems是个好主意吗?,我们在StackOverf

  7. ruby - 检查是否通过 require 执行或导入了 Ruby 程序 - 2

    如何检查Ruby文件是否是通过“require”或“load”导入的,而不是简单地从命令行执行的?例如:foo.rb的内容:puts"Hello"bar.rb的内容require'foo'输出:$./foo.rbHello$./bar.rbHello基本上,我想调用bar.rb以不执行puts调用。 最佳答案 将foo.rb改为:if__FILE__==$0puts"Hello"end检查__FILE__-当前ruby​​文件的名称-与$0-正在运行的脚本的名称。 关于ruby-检查是否

  8. postman——集合——执行集合——测试脚本——pm对象简单示例02 - 2

    //1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json

  9. ruby-on-rails - rbenv:从 RVM 移动到 rbenv 后,在 Jenkins 执行 shell 中找不到命令 - 2

    我从Ubuntu服务器上的RVM转移到rbenv。当我使用RVM时,使用bundle没有问题。转移到rbenv后,我在Jenkins的执行shell中收到“找不到命令”错误。我内爆并删除了RVM,并从~/.bashrc'中删除了所有与RVM相关的行。使用后我仍然收到此错误:rvmimploderm~/.rvm-rfrm~/.rvmrcgeminstallbundlerecho'exportPATH="$HOME/.rbenv/bin:$PATH"'>>~/.bashrcecho'eval"$(rbenvinit-)"'>>~/.bashrc.~/.bashrcrbenvversions

  10. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

随机推荐