Javascript:无法在递归函数调用中重新赋值变量

时间:2014-09-11 05:26:14

标签: javascript variables recursion global-variables

在下面的代码中,我检查一串字符是否是" spellable"在某个网格中,类似于拼字游戏。如果字母直接位于当前字母的上方,下方,左侧或右侧,则可以使用这些字母。例如," bcd"应该返回TRUE,而" bcdn"应该返回FALSE。

这些函数的执行完全符合我的预期,外,用于第32-33行。根据我的理解,wordExists = true行应覆盖第9行的原始声明。

我错过了什么?

repl.it link = http://repl.it/Yhh/5

var grid = [
    ['a','b','c','d'],
    ['e','f','g','h'],
    ['i','j','k','l'],
    ['m','n','o','p']
];

function doesWordExist(word, grid) {
    var wordExists = false;
    for (var i = 0, end = grid.length; i < end; i++){
        for (var j = 0, stop = grid[0].length; j < stop; j++) {
            if (word[0] === grid[i][j]) {
                doesLetterExist(word, i, j, 1);
            }
        }
    }
    return wordExists;
}

function isMatch(letter,i,j) {
    return (
        grid[i] !== undefined && 
        grid[i][j] !== undefined &&
        letter === grid[i][j]
    );
}

function doesLetterExist(word, i, j, depth) {
    console.log('i:' +i + " - j:" + j);
    var letter = word[depth];
    if (letter === undefined) {
        wordExists = true;
        console.log('can\'t re-define global "wordExists" variable :-(');
    }
    if (isMatch(letter,i, j + 1)) { // look right, j + 1
        doesLetterExist(word, i, j + 1, depth + 1);
    } else if (isMatch(letter, i, j -1)) { // look left, j - 1
        doesLetterExist(word, i, j - 1, depth + 1);
    } else if (isMatch(letter, i - 1, j)) { // look up, i - 1
        doesLetterExist(word, i - 1, j, depth + 1);
    } else if (isMatch(letter, i + 1, j)) { // look down, i + 1
        doesLetterExist(word, i + 1, j, depth + 1);
    }
}

doesWordExist('bcd', grid);

谢谢!

编辑:我删除了“全球”这个词。从标题。我错误地将在第一个函数中实例化的变量称为全局变量。应该可以从其范围内的所有功能中获取和更改吗?这就是我所说的“全球化”,它对所有儿童功能都感到全球化。

2 个答案:

答案 0 :(得分:2)

您在第9行将wordExists定义为局部变量

var wordExists = false;

从上面的

中取出var

答案 1 :(得分:1)

  

应该可以从其范围内的所有功能中获取和更改吗?它对所有儿童功能都感到全球化。

是。只有isMatchdoesLetterExist不是doesWordExist的子功能!它们在身体外宣布。我们需要嵌套它们,以便它们可以访问其父作用域:

function doesWordExist(word, grid) {
    var wordExists = false;
    for (var i = 0, end = grid.length; i < end; i++){
        for (var j = 0, stop = grid[0].length; j < stop; j++) {
            if (word[0] === grid[i][j]) {
                doesLetterExist(word, i, j, 1);
            }
        }
    }
    return wordExists;

    function doesLetterExist(word, i, j, depth) {
        console.log('i:' +i + " - j:" + j);
        var letter = word[depth];
        if (letter === undefined) {
            wordExists = true;
        }
        if (isMatch(i, j + 1)) { // look right, j + 1
            doesLetterExist(word, i, j + 1, depth + 1);
        } else if (isMatch(i, j -1)) { // look left, j - 1
            doesLetterExist(word, i, j - 1, depth + 1);
        } else if (isMatch( i - 1, j)) { // look up, i - 1
            doesLetterExist(word, i - 1, j, depth + 1);
        } else if (isMatch(i + 1, j)) { // look down, i + 1
            doesLetterExist(word, i + 1, j, depth + 1);
        }
        function isMatch(i, j) {
            return grid[i] !== undefined && 
                   grid[i][j] !== undefined &&
                   letter === grid[i][j];
        }
    }
}

类似地,isMatch函数现在可以访问letter变量,因为它是doesLetterExist函数的一部分,它不再需要作为参数传递。


但是,虽然您的功能现在可以正常工作,但它仍然不是最佳选择。当wordExists设置为true时,您应该能够突破doesWordExist - 您已经知道解决方案了。目前,你继续循环 - 这是一个非常沉重的循环。尝试改进原始算法(使用3个单独的函数),这样您就不会拥有“全局”wordExists变量,而是在每个函数中仅使用 return - doesLetterExist应该在找到该字母时立即return true,并且只有在筛选完所有递归调用后才返回false