9

我正在重构我的代码。我无法决定如何准确地实现我拥有的几个实用功能。 具体来说,如果某些功能在我的个人命名空间中更好,或者直接扩展 js 对象。

扩展原生 JavaScript 对象的示例

(这是正确的术语吗?)。

String.prototype.prettyDate = function(){
  return (this.substr(5,2) + '/' + this.substr(8) + '/' + this.substr(0,4));
}
var myString = "2010-12-27";
//logs 12/27/2010
console.log(myString.prettyDate);

使用我自己的命名空间的示例

var myNamespace = (function(){
   var my = {};
   my.prettyDate = function ( dateStr ){
      return (dateStr.substr(5,2) + '/' + dateStr.substr(8) + '/' + dateStr.substr(0,4));
   }
return my;
}());
var pretifiedDate = myNamespace.prettyDate('2010-12-27');
//logs 12/27/2010
console.log(pretifiedDate);

需要考虑的问题

  1. 何时将实用程序合理地插入到原生 JavaScript 对象中?
  2. 如何判断实用程序何时最好位于我自己的命名空间中?
4

5 回答 5

7
  1. 几乎从来没有,因为:

    a/ 可能与其他库发生冲突

    b/ 扩展函数被in操作符迭代为属性,除非被hasOwnProperty(不常用)过滤掉,否则会带来问题

    您可以为小型的单一脚本工作证明这一点,但前提是您 200% 确定没有人,永远不会尝试在某处重用该代码。在这种情况下,仅将其用于跨越多个代码模块的功能。用 trim() 扩展字符串 - 好的,用 prettyDate() 扩展字符串 - 值得怀疑,用 displayAsPageHeader() 扩展 Object - 可怕。

  2. 所以,几乎总是。

于 2010-12-28T03:19:52.650 回答
4

看这个视频:

John Resig 认为扩展本机对象是灾难的根源,特别是当框架或应用程序可能会发展成远远超出最初预期的东西时。

于 2010-12-28T03:21:25.183 回答
2

不幸的是,这个问题没有“正确”的答案。这是一个很好的讨论,但我担心它会在这里关闭。是否应该扩展原生对象是一个主观的争论,如果你接受它有条件地可以回答“什么时候?” 是“取决于”。

如果您可以控制它的使用以及它是否会与其他代码冲突,那么您真的没有理由不应该这样做。它非常方便,并且可以显着减少代码大小。

扩展本机对象存在的真正问题是,当您在扩展程序旁边运行其他代码时,可能期望具有相同属性名称的不同扩展程序,或者可能在for(var i in obj)没有防范原型链上的扩展的情况下粗心地使用。

于 2010-12-28T03:21:20.870 回答
1

好的...我不是这方面的专家,但几乎从不!你做的事情在你的命名空间内更安全。如果您遵循模块模式http://www.yuiblog.com/blog/2007/06/12/module-pattern/ ,一切正常

然而,有一些小技巧可以让我们避免覆盖其他命名空间。每个例子:

var myNamespace = {}; //my namespace, unsafely written

//Better solution
if(typeof myNamespace === 'undefined'){
    var myNamespace = {};
}

//Shorter solution
var myNamespace = myNamespace || {};
于 2010-12-28T03:30:15.830 回答
0

这取决于您对正在运行/加载的代码的控制程度:

  1. 如果这一切都在您的控制之下,那么扩展内置对象并没有错,JavaScript 旨在能够做到这一点。唯一的问题是,当两个库更改相同的内容时,您可能会遇到意想不到的问题。幸好你不会这样对自己,对吧?

  2. 如果您不知道/不知道,命名空间会更安全,尽管它笨重且冗长。这总是更安全。

就个人而言,我更喜欢第二种选择,因为我不喜欢过于冗长的代码并且命名空间看起来很有趣。

于 2010-12-28T04:56:41.937 回答