一、背景:

十月27号,我写过《给JavaScript的Array对象添加两个最大最小值方法》,非常简洁。今天我发现,这个简洁的实现给我惹了点麻烦。如果有一个数组,里面并不全为数字,那么,简洁版实现的最大最小值方法,将返回NaN对象,即Not a Number。

二、目标:

我希望达到的效果是,如果数组里面不全为有限数字,最大最小值方法仍然能够返回其中的有限数字部分的最大最小值。如果全不为数字,则最大值方法返回-Infinity,最小值方法返回Infinity,让调用者知道程序返回了无意义的结果。

三、解决方案:

显然,需要对Array对象再添加一个筛选有限数字的方法。怎样筛选呢?又需要添加一个判断一个对象是否为有限数字的方法,我把这个判断一个对象是否是有限数字的方法添加到了Math对象中。如下:

    //
    // 判断一个对象是否是有限数字
    //
    Math.isFiniteNumber = function (o) {
        if(typeof o === "number") {
            return !isNaN(o) && isFinite(o);
        } else {
            return false;
        }
    };

 

上面的测试条件中使用了===。用VB多年后,学C的时候,看到==,我崩溃了。后来再学JavaScript,居然看到有===,于是再次崩溃。其实,===与==意思一样,就是判断是否相等,只不过===是更严格的相等。JavaScript中有undefined对象,你可以测试一下,undefined == null 返回 true,而 undefined === null 则返回 false。

有了这个,就可以给Array对象添加筛选有限数字的方法了。

    //
    // 筛选有限数字
    //
    Array.prototype.screenFiniteNumber = function () {
        var data = [];
        for(var i = 0; i < this.length; i++) {
            if(Math.isFiniteNumber(this[i])) {
                data.push(this[i]);
            }
        }
        return data;
    };

最后,是最大最小值方法。可以发现仅仅是将简洁版实现的this替换成了this.screenFiniteNumber():

    //
    // 给数组对象添加一个 min() 方法
    //
    Array.prototype.min = function () {
        return Math.min.apply(null, this.screenFiniteNumber());
    };

    //
    // 给数组添加一个 max() 方法
    //
    Array.prototype.max = function () {
        return Math.max.apply(null, this.screenFiniteNumber());
    };

四、效果:

点击这里运行

测试代码:

var a = [1, 2, 4, 5, "ab"];
alert("最大值:" + a.max());
alert("最小值:" + a.min());

 

输出:

imageimage