关于JavaScript闭包的事情一直困扰着我。一旦构造函数完成执行,使用var关键字创建的变量仍将存在于内存中。例:



function RangeCalculator(values) {
  var min = Infinity;
  var max = -Infinity;
  for (var i = 0; i < values.length; ++i) {
    min = Math.min(min, values[i]);
    max = Math.max(max, values[i]);
  }

  this.range = max - min;

  this.getMin = function() {
    return min;
  };
  this.getMax = function() {
    return max;
  };
}

r = new RangeCalculator([1, 2, 3, 4, 5]);
console.log("min: " + r.getMin() + ", max: " + r.getMax());

<p>Check the console</p>





在该代码中,除了构造函数中定义的函数之外,无法从任何地方访问minmax。这允许在JavaScript中创建私有成员变量。

但是,如果我只是想使用min和max变量来帮助我计算范围,但之后又不需要它们该怎么办。如果删除getMin和getMax函数,该怎么办。构造函数中使用的所有var声明的变量是否仍然存在并占用内存空间,包括for循环中的i

如果我将代码包装在自执行匿名函数中怎么办?

function RangeCalculator(values) {
    (function (t) {
        var min = Infinity;
        var max = -Infinity;
        for (var i = 0; i < values.length; ++i) {
            min = Math.min(min, values[i]);
            max = Math.max(max, values[i]);
        }
        t.range = max - min;
    })(this);
}

var r = new RangeCalculator([1, 2, 3, 4, 5]);
alert(r.range);

最佳答案

如果信息隐藏是自定义类型概念的一部分,那么答案肯定是肯定的。但是,构造函数应始终尽可能轻量地实现。所有其他构建逻辑都应是工厂方法的一部分。给定的示例代码可以重构为类似以下内容的代码...



var NumberRange = (function (global) {

    var
        Number    = global.Number,
        Math      = global.Math,

        math_min  = Math.min,
        math_max  = Math.max,

        MIN_VALUE = Number.NEGATIVE_INFINITY,
        MAX_VALUE = Number.POSITIVE_INFINITY,

        collectLimitingValues = function (collector, value) {
            collector.minValue = math_min(collector.minValue, value);
            collector.maxValue = math_max(collector.maxValue, value);
            return collector;
        },


        NumberRange = function NumberRange (min, max) {
            this.range = (max - min);

            this.getMin = function () {
                return min;
            };
            this.getMax = function () {
                return max;
            };
        },


        createNumberRange = function (numberValueList) {

        //  right place for sanitizing all arguments.

            var rangeLimitMap = numberValueList.reduce(
                collectLimitingValues, {
                    minValue: MAX_VALUE,
                    maxValue: MIN_VALUE,
                }
            );
            return (new NumberRange(
                rangeLimitMap.minValue,
                rangeLimitMap.maxValue
            ));
        }
    ;

    return {
        create: createNumberRange
    };

}(window));


var r = NumberRange.create([1, 2, 3, 4, 5]);
console.log("min: " + r.getMin() + ", max: " + r.getMax());

<p>Check the console</p>

07-24 18:24
查看更多