将下划线附加到Object原型,坏主意?

时间:2014-07-23 22:22:06

标签: javascript underscore.js ecmascript-5

常识是因为你可以增加原生类型,并不意味着你应该

增加原生类型原型是一个坏主意总是,唯一的例外是ECMAScript Spec中的polyfill行为。

在我们的项目中,我们使用了下划线,我很想知道为什么不直接在我们的对象上使用它提供的OOP样式?

var _ = require('underscore');
Object.defineProperty( Object.prototype, '_', {
    get: function() {
        return _(this);
    }
});

这使我们能够直接使用下划线方法,而不必决定在我们想要使用它的任何地方要求库,而是在那里简单地知道它并在适当时使用下划线功能进行标准化。

[1, 2, 3]._.contains(3); // true

var funcOnce = function() {
   console.log("hello");
}._.once();

funcOnce(); // "hello"
funcOnce(); // 

{one: 1, two: 2, three: 3}._.keys(); // ['one', 'two', 'three']

我相信我只通过修改本机对象上的单个(可能无用的_?)属性来限制损坏的范围。

假设_中没有引入原生Object属性,您能否看到这将如何回应我们开发我们的应用程序?

2 个答案:

答案 0 :(得分:1)

  

假设在Object中没有引入本地_属性,您能否看到这将如何回应我们开发我们的应用程序?

是。当你有avoided that the property shows up in for in loops时,你确实忘了提供一个二传手。这肯定会打猎你:

// let's start with this
Object.defineProperty( Object.prototype, '_', {
    get: function() {
        return "sorry";
    }
});
// now what do you expect the following statements to do?

> var x = {}; "_" in x;
true // meh, obvious
> var x = {_:"works"}; x._
"works" // this is hijackable in older browsers!
> var x = {}; x._ = "works"; x._
"sorry" // well…
(function(){"use strict"; var x={}; x._ = "works"; return x._; }())
unhandled TypeError: "Invalid assignment in strict mode" // ooops!
> _
"sorry" // ah, window._ inherits from Object.prototype as well
> _ = "works"; _
"sorry" // and prevents even simple global variable assignments

答案 1 :(得分:0)

您正在使用require获取下划线依赖项,可以为您提供许多优势(假设您正确使用它),例如:

  1. 自由地按需,按需和
  2. 加载依赖项
  3. 在代码的不同部分使用不同版本的依赖项的能力
  4. 如果您要开始在对象上使用下划线,则会失去这些优势,就像您将下划线用作全局变量一样。而且,到底是什么?所以你可以替换

    _([1, 2, 3]).contains(3)
    

    [1, 2, 3]._.contains(3)
    

    它可能不是一个坏主意™,但它似乎也不是一个特别好的。