2013-05-30 42 views
2

更换名称空间的全局变量JS我有一些在当前使用“全局”命名空间存储的参数作为全局变量单页面的Web应用程序共享代码与JS关闭

使用一个命名空间是在污染全局的“窗口”对象的改进,但似乎这样的代码是一个很好的候选人封闭坚持调用之间的值。我搞砸了一些想法,但似乎无法获得关闭权的语法。

下面是当前版本的伪码。所有的代码都在“um”命名空间中。当我的共享函数最初由我的应用程序中的新虚拟页面调用时,我需要存储名为'extraData'的JS对象的内容。该函数的后续调用没有获得“而额外”,所以我目前将其存储在“um.globals.extraData”如果underscore.js确定该参数是一个对象。

//*************************** 
// IMPLEMENTATION SAMPLE 
//*************************** 

// Define namespaces (not showing: um.grid, um.ajax, um.classes, um.constants, etc.) 
window.um = window.um || {}; 

um.globals = um.globals || {}; /* container for namespaced 'global' variables */ 

um.grid.loadOrUpdate = function (iOffset, isUpdate, extra) { 
    var ajaxParams = new um.classes.AjaxParams(); 
    //----- 

    // If 'extra' is an object, store it in a global for subsequent invocations 
    if (_.isObject(extra)) { 
     // This seems like it could be a closure candidate... 
     um.globals.extraData = extra; 
    } 

    ajaxParams.values = [um.constants.urlPathParams.grid]; 
    ajaxParams.verb = um.constants.httpVerbs.GET; 

    // Use the global variable 'extraData' 
    ajaxParams.extraData = um.globals.extraData; 

    um.ajax.callMessaging(ajaxParams); 
}; 

下面是一些伪代码,实际调用该函数:

//*************************** 
// INVOCATION SAMPLES 
//*************************** 

// 1st invocation from virtual page 'Alpha' 
um.grid.loadOrUpdate(0, false, { "alpha-key": "alpha-value" }); 

// 2nd invocation from virtual page 'Alpha' 
um.grid.loadOrUpdate(1, true); // will re-use the "alpha" object 

// 1st invocation from virtual page "Beta' 
um.grid.loadOrUpdate(0, false, { "beta-key": "beta-value" }); 

// 2nd invocation from virtual page 'Beta' 
um.grid.loadOrUpdate(1, true); // will re-use the "beta" object 

我怎么能杀um.globals.extraData,并用某种关闭内更换此um.grid.loadOrUpdate

编辑

下面是促使我问这个问题“的JavaScript模式”一些代码:

var setup = function() { 
    var count = 0; 
    return function() { 
     return (count += 1); 
    } 
}; 

// usage 
var next = setup(); 
next(); // returns 1 
next(); // returns 2 
next(); // returns 3 

回答

0

对我来说,目前还不清楚你试图通过封锁达到的目标。闭包允许你在当前范围内封装变量的状态,如果你试图创建对象的各种实例,每个实例都有自己的状态,这可能会很方便。

你可以通过在返回到以后可以调用的函数的引用这样一种方式实现loadOrUpdate做到这一点。当调用该函数时,该范围内的所有变量将为,其中包含,并保留函数创建时的值。

例如:

um.grid.loadOrUpdate = function (iOffset, extra) { 
    var ajaxParams = new um.classes.AjaxParams(); 
    //----- 

    ajaxParams.values = [um.constants.urlPathParams.grid]; 
    ajaxParams.verb = um.constants.httpVerbs.GET; 

    um.ajax.callMessaging(ajaxParams); 

    // Return a function used to update this data later 
    return function (newOffset) // Update function 
    { 
     // From within here, you'll have access to iOffset and extra as they exist at this point 
     window.alert("Key: " + extra.key + " - Changing offset from " + iOffset + " to " + newOffset); 
     iOffset = newOffset; 
    }; 
}; 

然后,您可以调用你的函数像这样,记住它会返回一个引用的函数:

var alpha = um.grid.loadOrUpdate(0, { "key": "alpha-value" }); 
var beta = um.grid.loadOrUpdate(0, { "key": "beta-value" }); 

当你调用alpha()beta()中,价值额外将通过关闭保留,因此没有必要保持全球参考。

alpha(1); // Update from 0 to 1 
alpha(2); // Update from 1 to 2 
beta(3); // Update from 0 to 3 
beta(4); // Update from 3 to 4 

Example

不过,如果你试图保持extra单个实例,为loadOrUpdate共享所有来电,你可能会更好使用以前的技术,只是存储电流值作为函数本身的属性,或者该函数范围内的任何其他位置。

+0

我开始认为摆脱我的命名空间'全局'可能不是'loadOrUpdate ”。正如你所提到的,我只需要一个“loadOrUpdate”实例,原始实现很好。 'um.globals ...'中的值不会污染窗口名称空间,而名称'globals'则清楚地表明存储在其中的任何值都旨在全局范围内'um ...'我认为这是一种情况试图过度优化或过度设计已经运行良好的东西。全局变量本质上不是邪恶的。 :-) –

+0

同意,这听起来像你有什么好.. –

0

就是这种方法,你以后在做什么?

var ns = {}; 
(function() { 
var globals; 
ns.func = function(update,opts) { 
    if(update)opts=globals; 
    else globals=opts; 
    console.log(opts); 
} 
})(); 

ns.func(false,"a"); 
ns.func(true); 
ns.func(false,"b"); 
ns.func(true); 

输出:

a 
a 
b 
b 

我已经在周围(在这种情况下窗口)范围范围的一个匿名函数内部的全局变量,并提供在该函数中声明的函数的对象上 - 所以它可以访问'globals'变量,但它在外面不可见。

+0

它*看起来像你的实现仍然非常接近我的'ns.func'之外的全局变量被用来捕获'opts'。我将用来自“Javascript Patterns”的封闭示例更新我的原始问题,该示例最初使我认为内联闭包是消除全局变量的方法。 –

+0

是不是一样 - 在函数范围内隐藏一个变量?在我的例子中,变量'globals'在全局范围中不可见。这个名字很糟糕,但是我保留这个名字以表明它在原始示例中的用途。变量'globals'隐藏在匿名函数的作用域中。 – sync

+0

这里有一个参考,以防术语混淆(我只是自己查看它!):“内部函数引用其外部函数的局部变量创建闭包”http://robertnyman.com/2008/10/09/explaining- javascript-scope-and-closures/...这就是我的例子,一个由内部函数引用的变量,范围在外部函数中,在全局范围内不可见。类似于Crockford的私有变量实现IIRC。 – sync