2

查看如何在 Javascript Array 中查找最大值/最小值的不同方法,我经常可以看到扩展 Array 对象本身的原型。所以有:

var a=[22,33,44,32,1];

Array.max=function(v) { 
    return Math.max.apply(this,v); 
};

Array.max(a); // returns 44

但是我经常这样做:

Array.prototype.max=function() { 
    return Math.max.apply(this,this); 
};

a.max(); // returns 44

这允许我调用 Array 对象本身没有参数的 max()。就我个人而言,我认为它没有任何问题,我一直想知道我是否遗漏了什么,并且这种方法有一些我忽略的主要问题?使用 as 安全Array.max(arrayhere)吗?

编辑:说在第一个示例中我们在本机 Javascript Array 对象上创建静态方法并且在第二个示例中我们扩展 Arrays 原型是否正确?

4

2 回答 2

1

说在第一个示例中我们在本机 Javascript Array 对象上创建静态方法而在第二个示例中我们扩展 Arrays 原型是否正确?

是的。

就我个人而言,我认为它没有任何问题,我一直想知道我是否遗漏了什么,并且这种方法有一些我忽略的主要问题?

一些在数组上使用的人for in可能会绊倒您的可枚举max方法。虽然我个人认为他们应得的,但可以安全行事

使用 as 安全Array.max(arrayhere)吗?

是的,它避免了可枚举性问题。但是,您仍然需要考虑扩展 javascript natives 有其自身的问题,另请参阅为什么扩展原生对象是一种不好的做法?. 如果您还是选择了静态方法,那么将它们放在您自己的库对象上并不会使任何事情复杂化。

于 2014-01-28T14:49:52.840 回答
1

正确的方法是使用Object.definePropertyor Object.defineProperties。在这种情况下,我将写下如何使用后者。*编辑:请注意,这不会像您期望的那样处理空数组。请参阅下面的编辑。

Object.defineProperties(Array.prototype, {
    max: {
    configurable: true,
    enumerable: false,
    value: function () {return Math.max(...this)},
    writable: true
  },
    min: {
    configurable: true,
    enumerable: false,
    value: function () {return Math.min(...this)},
    writable: true
  }
});

然后你可以这样做:

[4, 3, 2, 1].max() // 4
[4, 3, 2, 1].min() // 1

这将防止任何人陷入for in陷阱,因为您将这些属性可枚举性设置为 false。

编辑。处理空数组

正如@MikeM 在他的评论中指出的那样,记录在案的行为和可能不是更有意义的——至少对我而言——。如果你不向这些函数发送参数,你会得到,在每种情况下都有不同的符号:Math.max()Math.min()Infinity

Math.max(); // -Infinity
Math.min(); // Infinity

因此,如果我们调用.max()或调用的数组.min()为空,我们将得到一个可以说是不那么合理的结果。为了处理这种边缘情况,解决方案是:

Object.defineProperties(Array.prototype, {
    max: {
    configurable: true,
    enumerable: false,
    value: function () {
            if (this.length === 0) return null; // or whatever makes more sense
            return Math.max(...this)
        },
    writable: true
  },
    min: {
    configurable: true,
    enumerable: false,
    value: function () {
            if (this.length === 0) return null;
            return Math.min(...this)
        },
    writtable: true
  }
});
于 2017-12-04T17:28:54.307 回答