草庐IT

JavaScript:扩展元素原型(prototype)

coder 2024-07-26 原文

我看到很多关于扩展 Element 的讨论。据我所知,这些是主要问题:

  • 可能会和其他库冲突,
  • 它将未记录的功能添加到 DOM 例程中,
  • 它不适用于旧版 IE,并且
  • 它可能会与 future 的变化发生冲突。

给定一个没有引用其他库的项目,文档更改,并且不在乎历史浏览器:

是否有任何技术理由不扩展 Element 原型(prototype)。这是一个有用的示例:

Element.prototype.toggleAttribute=function(attribute,value) {
    if(value===undefined) value=true;
    if(this.hasAttribute(attribute)) this.removeAttribute(attribute);
    else this.addAttribute(attribute,value);
};

我看过太多关于扩展原型(prototype)的弊端而没有提供合理解释的评论。

注1:上面的例子可能太明显了,因为toggleAttribute是 future 可能添加的那种方法。为了便于讨论,假设它名为 manngoToggleAttribute

注意 2:我已经删除了该方法是否已经存在的测试。即使这样的方法已经存在,覆盖它也更容易预测。无论如何,我假设这里的要点是方法尚未定义,更不用说实现了。这就是重点。

注意 3:我看到现在有一​​个名为 toggleAttribute 的标准方法,它的行为并不完全相同。经过修改,以上内容将是一个简单的 polyfill。这不会改变问题的重点。

最佳答案

还好吗?技术上是的。您应该扩展 native API 吗?根据经验,没有。不幸的是,答案更为复杂。如果您正在编写像 Ember 或 Angular 这样的大型框架,那么这样做可能是个好主意,因为如果更好的 API 便利性,您的消费者将受益。但如果你只是为自己做这件事,那么经验法则就是不行。

理由是这样做会破坏对该对象的信任。换句话说,通过添加、更改、修改原生对象,它不再遵循任何其他人(包括你 future 的自己)所期望的已被充分理解和记录的行为。

这种风格隐藏了可能不被注意的实现。 这个新方法是什么?它是一个 secret 的浏览器吗?它有什么作用?我发现了一个错误吗?立即向 Google 或 Microsoft 报告此问题?。有点夸张,但重点是 API 的真相现在已经改变,在这种情况下是出乎意料的。它使可维护性需要额外的思考和理解,如果您只是使用自己的函数或包装器对象则不会如此。这也使更改变得更加困难。

相关帖子:Extending builtin natives. Evil or not?

与其试图破坏别人的(或标准的)代码,不如使用您自己的代码。

function toggleAttribute(el, attribute, value) {
  var _value = (value == null ? true : value;
  if (el.hasAttribute(attribute)) {
    el.removeAttribute(attribute);
  } else {
    el.addAttribute(attribute, _value);
  }
};

现在它是安全的、可组合的、可移植的和可维护的。再加上其他开发人员(包括您 future 的自己)不会摸不着头脑,不知道这个没有记录在任何标准或 JS API 中的神奇方法来自哪里。

关于JavaScript:扩展元素原型(prototype),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38386662/

有关JavaScript:扩展元素原型(prototype)的更多相关文章

  1. ruby - 使用 C 扩展开发 ruby​​gem 时,如何使用 Rspec 在本地进行测试? - 2

    我正在编写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,我会写一个失败的规范,然后处理代码直到它通过,等等......在“ext/mygem/mygem.c”中我的C扩展和在gemspec的“扩展”中配置的有效extconf.rb,如何运行我的规范并仍然加载我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?这可能是个愚蠢的问题,但是从我的gem的开发源代码树中输入“bundleinstall”不会构建任何native扩展。当我手动运行rubyext/mygem/extconf.rb时,我确实得到了一个Makefile(在整个项目的根目录中),然后当

  2. c - mkmf 在编译 C 扩展时忽略子文件夹中的文件 - 2

    我想这样组织C源代码:+/||___+ext||||___+native_extension||||___+lib||||||___(Sourcefilesarekeptinhere-maycontainsub-folders)||||___native_extension.c||___native_extension.h||___extconf.rb||___+lib||||___(Rubysourcecode)||___Rakefile我无法使此设置与mkmf一起正常工作。native_extension/lib中的文件(包含在native_extension.c中)将被完全忽略。

  3. ruby - 在哈希的键数组中追加元素 - 2

    查看我的Ruby代码:h=Hash.new([])h[0]=:word1h[1]=h[1]输出是:Hash={0=>:word1,1=>[:word2,:word3],2=>[:word2,:word3]}我希望有Hash={0=>:word1,1=>[:word2],2=>[:word3]}为什么要附加第二个哈希元素(数组)?如何将新数组元素附加到第三个哈希元素? 最佳答案 如果您提供单个值作为Hash.new的参数(例如Hash.new([]),完全相同的对象将用作每个缺失键的默认值。这就是您所拥有的,那是你不想要的。您可以改用

  4. 「Python|Selenium|场景案例」如何定位iframe中的元素? - 2

    本文主要介绍在使用Selenium进行自动化测试或者任务时,对于使用了iframe的页面,如何定位iframe中的元素文章目录场景描述解决方案具体代码场景描述当我们在使用Selenium进行自动化测试的时候,可能会遇到一些界面或者窗体是使用HTML的iframe标签进行承载的。对于iframe中的标签,如果直接查找是无法找到的,会抛出没有找到元素的异常。比如近在咫尺的例子就是,CSDN的登录窗体就是使用的iframe,大家可以尝试通过F12开发者模式查看到的tag_name,class_name,id或者xpath来定位中的页面元素,会抛出NoSuchElementException异常。解决

  5. ruby - Hanami link_to 助手只呈现最后一个元素 - 2

    我是HanamiWorld的新人。我已经写了这段代码:moduleWeb::Views::HomeclassIndexincludeWeb::ViewincludeHanami::Helpers::HtmlHelperdeftitlehtml.headerdoh1'Testsearchengine',id:'title'hrdiv(id:'test')dolink_to('Home',"/",class:'mnu_orizontal')link_to('About',"/",class:'mnu_orizontal')endendendendend我在模板上调用了title方法。htm

  6. ruby-on-rails - 向 Rails 3 添加 Ruby 扩展方法的最佳实践? - 2

    我有一个要在我的Rails3项目中使用的数组扩展方法。它应该住在哪里?我有一个应用程序/类,我最初把它放在(array_extensions.rb)中,在我的config/application.rb中我加载路径:config.autoload_paths+=%W(#{Rails.root}/应用程序/类)。但是,当我转到railsconsole时,未加载扩展。是否有一个预定义的位置可以放置我的Rails3扩展方法?或者,一种预先定义的方式来添加它们?我知道Rails有自己的数组扩展方法。我应该将我的添加到active_support/core_ext/array/conversion

  7. ruby - 将n维数组的每个元素乘以Ruby中的数字 - 2

    在Ruby中,是否有一种简单的方法可以将n维数组中的每个元素乘以一个数字?这样:[1,2,3,4,5].multiplied_by2==[2,4,6,8,10]和[[1,2,3],[1,2,3]].multiplied_by2==[[2,4,6],[2,4,6]]?(很明显,我编写了multiplied_by函数以区别于*,它似乎连接了数组的多个副本,不幸的是这不是我需要的)。谢谢! 最佳答案 它的长格式等价物是:[1,2,3,4,5].collect{|n|n*2}其实并没有那么复杂。你总是可以使你的multiply_by方法:c

  8. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

    我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

  9. arrays - 计算数组中的匹配元素 - 2

    给定两个大小相等的数组,如何找到不考虑位置的匹配元素的数量?例如:[0,0,5]和[0,5,5]将返回2的匹配项,因为有一个0和一个5共同;[1,0,0,3]和[0,0,1,4]将返回3的匹配项,因为0有两场,1有一场;[1,2,2,3]和[1,2,3,4]将返回3的匹配项。我尝试了很多想法,但它们都变得相当粗糙和令人费解。我猜想有一些不错的Ruby习惯用法,或者可能是一个正则表达式,可以很好地回答这个解决方案。 最佳答案 您可以使用count完成它:a.count{|e|index=b.index(e)andb.delete_at

  10. ruby - 如何在 ruby​​ 中复制目录结构,不包括某些文件扩展名 - 2

    我想编写一个ruby​​脚本来递归复制目录结构,但排除某些文件类型。因此,给定以下目录结构:folder1folder2file1.txtfile2.txtfile3.csfile4.htmlfolder2folder3file4.dll我想复制这个结构,但不包含.txt和.cs文件。因此,生成的目录结构应如下所示:folder1folder2file4.htmlfolder2folder3file4.dll 最佳答案 您可以使用查找模块。这是一个代码片段:require"find"ignored_extensions=[".cs"

随机推荐