2013-04-11 2 views
6

У меня есть функция, в которой я использую замыкание следующим образом:Может ли хранить большие переменные в замыкании, вызывают проблемы?

function myobject() { 
    var width=300, 
     height=400, 
     bigjsondata = { } // assume this is a big variable ~ 300k 

    function obj(htmlelement) { 
    // plot a graph in this htmlelement based on bigjsondata 
    } 

    return obj; 
} 

var plot1 = myobject(); 
plot1('#holder1'); 

var plot2 = myobject(); 
plot1('#holder2'); 

переменная bigjsondata содержит большой набор данных. Вопрос в том, выделяет ли память bigjsondata всякий раз, когда я создаю переменную var a = myobject()?

Может ли это привести к проблемам с памятью, если создано много экземпляров?

Если да, то каков наилучший способ загрузить его только один раз? (bigjsondata не меняется)

Edit: В конце я хотел бы myobject быть доступной по всему миру.

+0

Да; Да; Использовать только одну переменную (меньше локальной области) – Bergi

+0

Почему вы говорите, что 'bigjsondata' не изменяется, когда' obj.data' является функцией setter для него? – Bergi

+0

О, моя ошибка. Я должен удалить функцию сеттера. – Nasir

ответ

3

не уверен, что вы пытаетесь достичь, это должно предоставить вам некоторые частные хранения на различных уровнях:

var privateStorage = function() { 
    // only 1 copy total 
    var bigJsonData = {...} 
    return function() { 
    // 1 copy for each instance 
    var instanceData = {...} 
    return function() { 
      // something to do many times per instance 
      return something_useful 
    } 
    } 
}(); // returns function that privatelly knows about bigJsonData 

var a = privateStorage(); // a is now 1st instance of the inner-most function 
var b = privateStorage(); // a and b share the SAME bigJsonData object, but use different instanceData objects 

a1 = a(); 
a2 = a(); 
+0

+1 для возврата функции, а не того, что я использовал в своем ответе. –

3

Вообще - да, код выглядит следующим образом создавая новый экземпляр для bigjsondata каждый раз, когда вы делаете new myObject(); Чтобы получить Arround вопрос, вы можете использовать анонимную функцию инициализации, как это:

myObject = null; 

(function() { 
    var bigjsondata = { ... } // construct you large object here; 

    function myObjectInternal() { 
     // you can access `bigjsondata` from here. 
     // do not change `bigjsondata`, since it will now 
     // use the changed value in all new instances of `myObjectInternal` 
    } 
    myObjectInternal.prototype = { 
     data: function(_) { 
      // you can access `bigjsondata` from here too 
     } 
    }; 

    myObject = myObjectInternal; 
})(); 

Это создаст анонимную функцию, которая вызывается сразу и только один раз (например, один синглтон). Внутри функции bigjsondata является замыканием функции myObjectInternal, которая видна только в анонимной форме. Вот почему вы определяете внешнюю глобальную переменную myObject, чтобы последняя указывала на функцию/объект myObjectInternal.

Определите myObjectInternal, как и у вас было бы myObject, и вам хорошо идти. Таким образом, в следующем коде:

var instance1 = new myObject(); 
var instance2 = new myObject(); 

он будет использовать тот же bigjsondata для instance1 и instance2

+0

Этот код является синтаксической ошибкой. – Bergi

+0

@ Bergi, спасибо, я исправил его –

+0

Можете ли вы привести пример кода того, как именно вы можете получить доступ к bigjsondata из 'instance1' и' instance2'? – ducin

1

Я бы предложил пойти для объектно-ориентированного подхода для этого.

function obj (htmlelement) 
{ 
    this.htmlelement = $(htmlelement);  
} 

obj.prototype.htmlelement = null; 
obj.prototype.bigjsondata = {}; 
obj.prototype.width = 300; 
obj.prototype.height=400; 

obj.prototype.plot = function() 
{ 
    var htmlelement = this.htmlelement; 
    var bigjsondata = this.bigjsondata; 
    var width = this.width; 
    var height = this.height; 
    //plot graph here; 
} 

var plot1 = new obj('#holder1'); 
var plot2 = new obj('#holder2'); 
plot1.plot(); 
plot2.plot(); 

Здесь одни и те же bigjsondata будут совместно использоваться всеми объектами obj.

Смежные вопросы