简体   繁体   English

如何在不同的javascript模块中共享变量

[英]how to share variables in different javascript modules

I want to know if it is possible to share variables in different module. 我想知道是否可以在其他模块中共享变量。

For example,in my common module,I define some global variable and util methods 例如,在我的common模块中,我定义了一些全局变量和util方法

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

While in anothe module,I want to access the name variable,for example, in the app module: 在另一个模块中时,我想访问name变量,例如在app模块中:

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

However I do not want to export the name to global context. 但是,我不想将name导出到全局上下文。

Is it possible? 可能吗?

Update 更新资料


Why I ask this question is I found google do this: 为什么我问这个问题是我发现谷歌这样做:

In the google map example page : 在Google地图示例页面中

It load the following js: main.js 它加载以下js: main.js

Whose content is: 谁的内容是:

((function(){ //xxxxxx }).call(this); ((function(){// xxxxxx})。call(this);

Then it load the map compnets like this: 然后按如下方式加载地图 compnet:

google.maps. 谷歌地图。 _ gjsload _ ('map', '\\'use strict\\';function Ut(){}function Vt(a,b,c).......'); _ gjsload _ ('map','\\'use strict \\'; function Ut(){} function Vt(a,b,c).......');

While the map module can use the variables in the main module. map模块可以使用main模块中的变量。

Edit: 编辑:

It's perfectly simple: if you open your console on the example page, and look at the source of main.js (click the button in the bottom left corner that looks like [{}] ) you'll notice that the entire script is one big function, that is called using .call(this) . 这非常简单:如果在示例页面上打开控制台,然后查看main.js的源代码(单击左下角看起来像[{}]的按钮),您会注意到整个脚本是一个大函数,使用.call(this)调用。 The latter is necessary because of strict mode (which shields the global object, unless it's explicitly set as caller context). 由于严格模式(除非将全局对象显式设置为调用者上下文,否则它将屏蔽全局对象),后者是必需的。
This function declares all functions, objects and methods in this function's scope, forming a closure. 该函数声明该函数范围内的所有函数,对象和方法,从而形成一个闭包。 It therefore stands to reason that all functions declared in this scope have access to all variables, too. 因此,有理由认为,在此范围内声明的所有函数也都可以访问所有变量。 In the end the google property is assigned as a property of the global object, thus exposing the closure. 最后,将google属性分配为全局对象的属性,从而公开了闭包。

(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

For all I know this might not look all that clear, but essentially, what happens is this: each function has its own scope. 就我所知,这可能看起来还不是很清楚,但是从本质上讲,会发生什么:每个函数都有自己的作用域。 All variables declared in that scope are garbage collected (GC'ed) when that function returns Unless there is an object that references them. 该函数返回时,在该范围中声明的所有变量都将被垃圾回收(GC'ed), 除非有一个引用它们的对象。
In this case google is an object, declared in the anonymous function's scope. 在这种情况下,google是一个在匿名函数范围内声明的对象。 A reference to this google object was then assigned to the global object, it just happens to have the same name as the object variable, but it could just as well have been exposed like so: 然后,将对这个google对象的引用分配给全局对象,它恰好与对象变量具有相同的名称,但是它也可能像这样被公开:

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

Google is a property of the global object, that references an object created in the function's scope. Google是全局对象的属性,它引用在函数范围内创建的对象。 The object it references keeps the function's scope (and all of the variables declared in that scope) alive. 它引用的对象使函数的作用域(以及在该作用域中声明的所有变量)保持活动状态。 That's why it might seem that you have access to the closure variables almost directly, but again, it's a REFERENCE . 这就是为什么您似乎几乎可以直接访问闭包变量的原因,但这又是一个REFERENCE If you're familiar with C(++) programming, here's what happens in pseudo-code: 如果您熟悉C(++)编程,这就是伪代码中发生的事情:

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

Basically the global google contains nothing more then the memory address of the actual google object, it points to it, it references it, it just tells JS where to look for the values in memory,... 基本上,全局google包含实际google对象的内存地址,它指向它,引用它,它只是告诉JS在哪里寻找内存中的值,...
The actual object cannot be accessed directly, it sits somewhere in memory, along with all local variables that were declared along with it, who all have addresses, too, but the global object doesn't know about those. 实际对象无法直接访问,它与一起声明的所有局部变量一起位于内存中的某个地方,它们也都有地址,但是全局对象不知道这些地址。 It just goes to the one address it knows of, asks for whatever it needs and the original google object complies. 它只是转到它知道的一个地址,询问它需要什么, 原始的 google对象就符合了。

I'm terrible at explaining all this in a coherent, comprehensive way, but perhaps this article might shed some light on this matter. 我很难以连贯,全面的方式来解释所有这一切,但是也许这篇文章可以使您对此有所了解。 When I started to look into closures, I found the diagrams very helpful. 当我开始研究闭包时,发现图非常有用。


You can't, not as such. 你不能,不是那样。 The whole point of closures is that you can set variables that can only be referenced in that specific scope. 闭包的全部目的是可以设置只能在该特定范围内引用的变量。 What you can do, however is use priviliged methods , or (not to good practice, but possible) full on assigning a variable to the global object. 但是,您可以做的是使用特权方法 ,或者(不是很好的做法,但有可能)将变量分配给全局对象。

(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

If you really, really need globals: 如果您确实需要全局变量:

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'

But best of all, especially in your case (access certain "private" variables) a privileged getter would seem the best way to go: 但是最重​​要的是,特别是在您的情况下(访问某些“私有”变量),特权获取者似乎是最好的选择:

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

That should do it 那应该做

UPDATED after correct criticism of Quentin and Elias 在对昆汀和埃里亚斯的正确批评后更新

You could define your module like this: 您可以这样定义模块:

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

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

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

And now access name outside of the module using 现在使用以下命令访问模块外部的名称

var kk = module.name;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM