2015-05-04 45 views
0

有些東西一直在困擾着我關於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中創建私有成員變量。

但是,如果我只是想使用最小和最大變量來幫助我計算範圍,但之後並不需要它們。如果我刪除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); 
+0

的可能重複[如何JavaScript的閉包垃圾回收(http://stackoverflow.com/questions/ 19798803/how-javascript-closures-are-garbage-collected) – ekuusela

+0

@ekuusela謝謝你。從我的理解,這意味着瀏覽器將始終保持關閉內存,或者至少它會如果有一個函數在構造函數中聲明。 http://jsfiddle.net/gqpsv7z0/ –

+1

我也改變了作爲一個小提琴OP的例子 - http://jsfiddle.net/gqpsv7z0/1/。構造函數的內部IIFE應該在構造時間後進行垃圾回收,因爲它不會保持任何引用的活動狀態並僅返回原始值。 (相比之下,OP示例的IIFE將構造函數'this'引用永遠保存爲't')。因此,在後面的示例中創建一個'RangeCalculator'實例應該儘可能低內存消耗,並且也非常接近OP的示例。 –

回答

1

如果信息隱藏是自定義類型概念的一部分,那麼答案肯定是肯定的。儘管如此,構造函數應始終儘可能輕量級地實現。所有附加的構建邏輯應該是工廠方法的一部分。給出的示例代碼可以實現類似的像下面的東西進行重構......

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>

+0

對於這種確切的情況,我不會製造一個工廠對象,但感謝提醒我關於它們。 –

相關問題