Chcę wiedzieć, czy możliwe jest dzielenie zmiennych w innym module.

Na przykład, w module My common Definiuję niektóre globalne metody zmiennej i uteli

(function(){
  var name="";
})();

Podczas gdy w innym module chcę uzyskać dostęp do zmiennej {X0}}, na przykład w module app:

var kk=name; // access the name
//other thing

Jednak nie chcę wyeksportować kontekstu name.

Czy to możliwe?

Aktualizacja


Dlaczego zadaję to pytanie, czy go Google to:

W mapie Google przykładowa strona:

Ładuje następujące JS: main.js

Którego treści jest:

((funkcja () {// xxxxxx}). Wywołanie (to);

Następnie ładuje Map Compneny to:

Google.Maps. _ gjsload _ ("Mapa", "użyj ścisłego"; funkcja UT () {} VT (A, B, C) ....... ');

Podczas modułu map może używać zmiennych w module main.

0
hguser 14 wrzesień 2012, 15:24

2 odpowiedzi

Najlepsza odpowiedź

Edytuj:

Jest to idealne proste: jeśli otworzysz konsolę na przykładowej stronie i spójrz na źródło Main.js (kliknij przycisk w lewym dolnym rogu, który wygląda jak [{}]), zauważysz, że cały skrypt jest Jedna duża funkcja, która nazywana jest przy użyciu .call(this). Ten ostatni jest konieczny z powodu ścisłego trybu (który osłania globalny obiekt, chyba że jest jawnie ustawiony jako kontekst dzwoniącego).
Funkcja ta deklaruje wszystkie funkcje, obiekty i metody w zakresie tej funkcji, tworząc zamknięcie. Dlatego rozumie, że wszystkie funkcje zadeklarowane w tym zakresie mają również dostęp do wszystkich zmiennych. W końcu właściwość google jest przypisana jako właściwość obiektu globalnego, wystawiając w ten sposób zamknięcie.

(function()
{
    'use strict';
    console.log(this);//would be undefined
}).call(this);//but the global object is explicitly set as context, so this === window

(function()
{
    'use strict';
    var closureScope = 'Global object can\'t see me';
    var google = {visible:'Yes, I was assigned as a property to the global object'};
    google.closureScope = closureScope;//expose initial value of closureScopeVariable
    google.showBenefits = function()
    {//context here is google object, this points to google
        this.closureScope = 'I looked like the closure variable';//reassign
        console.log(this.closureScope === closureScope);//logs false
    };
    google.restoreOriginal = function()
    {
        this.closureScope = closureScope;//reassign closureScope's original value
    };
    //expose:
    this.google = google;
}).call(this);
//global object:
google.closureScope = 'Foobar';
google.restoreOriginal();
console.log(google.closureScope);//Global object can't see me

Dla wszystkich, wiem, że to może nie wyglądać na to wszystko, ale zasadniczo, co się dzieje: każda funkcja ma swój własny zakres. Wszystkie zmienne zadeklarowane w tym zakresie są zebrane śmieci (GC'ed), gdy ta funkcja zwraca , chyba że jest przedmiotem, który je odnosi.
W tym przypadku Google jest obiektem, zadeklarowany w zakresie funkcji anonimowej. Referencje do tego obiektu Google został następnie przypisany do globalnego obiektu, po prostu ma to taką samą nazwę jak zmienną obiektów, ale może to równie dobrze być narażona jak więc:

window.foobar = google;
window.foobar.closureScope;//works
window.google;//undefined

Google jest właściwością globalnego obiektu, że referencje obiekt utworzony w zakresie funkcji. Odniesienia obiektu zapewnia zakres funkcji (i wszystkie zmienne zadeklarowane w tym zakresie) żyją. Dlatego może się wydawać, że masz dostęp do zmiennych zamkniętej niemal bezpośrednio, ale znowu jest to referencje . Jeśli znasz programowanie C (++), oto co dzieje się w Pseudo-Code:

GoogleObj google = new Google();
GoogleObj &window.google = google;
//or in pseudo-C:
GoogleObj *google;
GoogleObj **window.google = &google;//pointer to pointer ~= reference

Zasadniczo globalny google nie zawiera nic więcej niż adres pamięci rzeczywistego obiektu Google, wskazuje na to, odwołuje się, po prostu mówi JS, gdzie szukać wartości w pamięci, ...
Rzeczywisty obiekt nie może być dostępny bezpośrednio, znajduje się gdzieś w pamięci, wraz ze wszystkimi zmiennymi lokalnymi, które zostały zadeklarowane wraz z nim, które wszyscy mają adresy, ale także globalny obiekt nie wie o tych. Po prostu idzie do jednego adresu, o którym wiadomo, prosi o to, co potrzebuje, a obiekt Oryginalny Google jest zgodny.

Jestem straszny w wyjaśnianiu tego wszystkiego w spójnym, kompleksowym sposobie, ale Być może ten artykuł może rzucić trochę światła w tej sprawie. Kiedy zacząłem przyjrzeć się zamknięciom, znalazłem diagramy bardzo pomocne.


Nie możesz, nie jako taki. Cały punkt zamknięcia jest to, że można ustawić zmienne, które można odwoływać tylko w tym konkretnym zakresie. To, co może , ale jest jednak stosować Priviliged Methal lub (nie do dobrej praktyki, ale możliwe) pełne przy przypisaniu zmiennej obiektu globalnego.

(function()
{
    var name = 'foo';
    //do stuff
    window.name = name;//expose to global object
})();//THIS IS BLUNT AND DANGEROUS

var safer = (function()
{
    var name = 'foo';
    return {name:name};
});
console.log(safer.name);//logs foo

Jeśli naprawdę naprawdę potrzebujesz globusów:

var safer = (function()
{
    var closureVars = {name:'foo'};
    var name = 'foo';
    return function(privateName,globalName)
    {
        globalName = globalName || privateName;
        window[globalName] = closureVars[privateName];
    };
});
safer('name');//sets window.name to 'foo'

Ale najlepsze ze wszystkich, zwłaszcza w twoim przypadku (dostęp niektórych "Prywatny" Getter wydawałby się najlepszym sposobem na pójście:

var module = (function()
{
    var closureVars = {name:'foo';}
    return {get:function(name)
        {
            return closureVars[name];
        },
        set:function(name,val)
        {
            closureVars[name] = val;
        }
    };
};
var name = module.get('name');//sets a global name variable to 'foo'
module.set('name2',module.get('name'));//and so on

Że należy to zrobić

1
Elias Van Ootegem 14 wrzesień 2012, 14:03

zaktualizowany po prawidłowej krytyce Quentin i Elias

Możesz zdefiniować swój moduł w ten sposób:

var module = (function(){
    // your module definition
    var module = {};

    // set name as a property of the module
    module.name="";

    // return the module object
    return module;
})();

A teraz dostęp do nazwy poza modułem za pomocą

var kk = module.name;
0
Asciiom 14 wrzesień 2012, 11:39