2013-04-11 10 views
6

Mam funkcji, w których używam zamknięcie następująco:Czy przechowywanie dużych zmiennych w zamknięciu może powodować problemy?

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'); 

zmienna bigjsondata zawiera duży zbiór danych. Pytanie brzmi: czy przydziela pamięć dla bigjsondata, gdy tylko utworzę zmienną var a = myobject()?

Czy może to prowadzić do problemów z pamięcią, jeśli tworzonych jest wiele instancji?

Jeśli tak, to jaki jest najlepszy sposób, aby załadować go tylko raz? (bigjsondata nie zmienia)

Edycja: Na koniec chciałbym myobject być dostępne globalnie.

+0

Tak; Tak; Używaj tylko jednej zmiennej (o mniejszym zasięgu lokalnym) – Bergi

+0

Dlaczego mówisz, że 'bigjsondata' nie zmienia się, gdy' obj.data' jest dla niego funkcją ustawiającą? – Bergi

+0

o mój błąd powinienem usunąć funkcję setera. – Nasir

Odpowiedz

3

nie wiem, co chce osiągnąć, to powinien dostarczyć jakiegoś prywatnego przechowywania na różnych poziomach:

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 za zwrócenie funkcji, a nie za to, co użyłem w mojej odpowiedzi. –

3

Generalnie - tak, kod wygląda tworzenie nowej instancji dla bigjsondata każdym razem dokonać new myObject(); Aby uzyskać arround problemu, można użyć anonimowego funkcji inicjalizacji takiego:

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; 
})(); 

To stworzy anonimowa funkcja, która jest wywoływana natychmiastowo i tylko raz (jak singleton). Wewnątrz funkcji bigjsondata jest zamknięciem funkcji myObjectInternal, która jest widoczna tylko w anonimowej. Dlatego definiujemy zewnętrzną zmienną globalną myObject, aby ta ostatnia wskazywała na funkcję/obiekt myObjectInternal.

Zdefiniuj myObjectInternal tak, jakbyś miał myObject i jesteś gotowy do pracy. Tak więc, w poniższym kodzie:

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

będzie korzystać z tego samego bigjsondata dla instance1 i instance2

+0

Ten kod jest błędem składni. – Bergi

+0

@Bergi, dzięki, naprawiłem to –

+0

możesz podać przykładowy kod jak dokładnie można uzyskać dostęp do bigjsondata z 'instancji1' i' instancji2'? – ducin

1

Proponuję podejście zorientowane obiektowo.

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(); 

Tutaj ta sama bigjsondata zostanie udostępniona wszystkim obiektom obj.

Powiązane problemy