JS变量范围:在一个函数中推入一个数组并访问另一个函数

时间:2015-01-30 14:53:39

标签: javascript

http://jsfiddle.net/ujapned5/

我试图创建一个"初始化程序"用于定义CSS id和类名的函数。

function init() {

    //our empty array for pushing
    var DivNamingPushArray = [];

    //object where we define our properties that will be used later
    var namingScheme = {
        "parentId": {
            "firstChild": "blah",
            "secondChild": "blahblah",
            "thirdChild": "blahblahblah"
        }
    }

    //loop through the namingScheme object and push into array
    for (propOne in namingScheme) {
        DivNamingPushArray.push(propOne);
        for (propTwo in namingScheme[propOne]) {
            DivNamingPushArray.push(namingScheme[propOne][propTwo])
        }
    }
}

function execute() {

    //call the "init" function
    init();

    //this cannot be called
    console.log(DivNamingPushArray);

    //however, why can this be successfully called?
    console.log(propOne);
}

execute();

我更愿意将这些功能分开,而不是在execute内包含init。稍后还需要调用DivNamingPushArray变量的其他函数。

我正在查看关于变量范围的MDN文档,但没有找到一个简单的解决方案......

5 个答案:

答案 0 :(得分:1)

我建议您使用第三个函数来分隔逻辑

至于propOne,你可以在你的问题中看到我的评论,只需将var放在它前面。

<强> Working example here

execute();

function init(app) {
    app.DivNamingPushArray = getNamingArray();
}

function execute() {
    var app = {};

    //call the "init" function
    init(app);

    console.log(app.DivNamingPushArray);

}

function getNamingArray() {
    //our empty array for pushing
    var DivNamingPushArray = [];

    //object where we define our properties that will be used later
    var namingScheme = {
        "parentId": {
            "firstChild": "blah",
            "secondChild": "blahblah",
            "thirdChild": "blahblahblah"
        }
    }

    //loop through the namingScheme object and push into array
    for (var propOne in namingScheme) {
        DivNamingPushArray.push(propOne);
        for (var  propTwo in namingScheme[propOne]) {
            DivNamingPushArray.push(namingScheme[propOne][propTwo])
        }
    }

    return DivNamingPushArray;
}

答案 1 :(得分:0)

当您声明一个没有关键字var的变量时,它变为全局变量。在var循环中声明变量之前添加for...in

for (var propOne in namingScheme) {
    DivNamingPushArray.push(propOne);
    for (var propTwo in namingScheme[propOne]) {
        DivNamingPushArray.push(namingScheme[propOne][propTwo])
    }
}

当变量变为全局变量或window的一部分时,可以在任何地方访问它。因此,始终使用var将变量保持在范围内,从而避免污染全局范围。

在您调用init后,propOnepropTwo已成为全局变量,因此可以在任何地方访问。对于DivNamingPushArray,将它声明为更高级别,因此它将对其他函数可见或尝试使用模块模式。

答案 2 :(得分:0)

我建议使用一些像模块一样的js模式来分隔它:

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#modulepatternjavascript

并使用像观察者这样的东西来让函数通信。

这不是一个简单的实施解决方案,但你可以玩得开心!

答案 3 :(得分:0)

如果您希望在DivNamingPushArray范围内访问execute(),请在init()声明之前将其声明提升一级:

//Declare your array outside of your init function
var DivNamingPushArray = [];

function init() {
   //...

对于propOne,请参阅Amit Joki的回答。

答案 4 :(得分:0)

Javascript变量范围的工作原理如下:

//this will not be changed in "init" function.
DivNamingPushArray = [];

//this will be changed because you don't localize your variable in init function
propone = 'value'; 

function init() {

    //this "var" declaration localizes the variable. 
    //You can do anything you want with it and 
    //the global DivNamingPushArray wont change.
    //The only way to use the global variable now is through 
    //the global object. (window.DivNamingPushArray for browsers)
    var DivNamingPushArray = [];

    // if you would have used "for (var propOne in namingScheme)",
    // the variable would have been local
    for (propOne in namingScheme) {
        // ...
    }
}