Javascript 吊装问题的范围或功能?我不确定

Javascript 吊装问题的范围或功能?我不确定,javascript,Javascript,如下所示,我制作了一个简单的高分数组,保存到本地存储,并在用户提示下添加到 作为一个独立的文件,它本身工作得很好。或者至少看起来是这样 然而,当我试图将其集成到我的大型应用程序中时,我的全局变量allScores似乎存在范围问题。数组的长度保持为0。我检查了一下是否有重复的变量,但没有 我一直在尝试阅读有关功能和范围的内容。我不确定的是,为什么下面的代码作为一个独立的文件工作,但当我将其集成到更大的应用程序中时,我会遇到范围问题 我应该怎样做才能有所不同?由于我不熟悉JavaScript,我的最

如下所示,我制作了一个简单的高分数组,保存到本地存储,并在用户提示下添加到

作为一个独立的文件,它本身工作得很好。或者至少看起来是这样

然而,当我试图将其集成到我的大型应用程序中时,我的全局变量allScores似乎存在范围问题。数组的长度保持为0。我检查了一下是否有重复的变量,但没有

我一直在尝试阅读有关功能和范围的内容。我不确定的是,为什么下面的代码作为一个独立的文件工作,但当我将其集成到更大的应用程序中时,我会遇到范围问题

我应该怎样做才能有所不同?由于我不熟悉JavaScript,我的最佳实践很可能已经过时了。感谢您的指导。谢谢

var allScores = [];

function saveScore() {

if (allScores.length === 0) {
    allScores[0]= prompt('enter score', '');
    localStorage ['allScores'] = JSON.stringify(allScores);
}

else if (allScores.length < 3) {
    var storedScores = JSON.parse(localStorage ['allScores']);
    storedScores = allScores;
    var injectScore = prompt('enter score', '');
    allScores.push(injectScore);
    allScores.sort(function(a, b) {return b-a});
    localStorage ['allScores'] = JSON.stringify(allScores);
}

else {
    var storedScores = JSON.parse(localStorage ['allScores']);
    storedScores = allScores;
    var injectScore = prompt('enter score', '');
    allScores.pop();
    allScores.push(injectScore);
    allScores.sort(function(a, b) {return b-a});
    localStorage ['allScores'] = JSON.stringify(allScores);
}
document.getElementById('readScores').innerHTML = allScores;
}**
var-allScores=[];
函数saveScore(){
如果(allScores.length==0){
allScores[0]=提示('输入分数','');
localStorage['allScores']=JSON.stringify(allScores);
}
否则如果(allScores.length<3){
var storedScores=JSON.parse(localStorage['allScores']);
StoredCores=所有分数;
var injectScore=提示('输入分数','');
allScores.push(injectscores);
sort(函数(a,b){返回b-a});
localStorage['allScores']=JSON.stringify(allScores);
}
否则{
var storedScores=JSON.parse(localStorage['allScores']);
StoredCores=所有分数;
var injectScore=提示('输入分数','');
allScores.pop();
allScores.push(injectscores);
sort(函数(a,b){返回b-a});
localStorage['allScores']=JSON.stringify(allScores);
}
document.getElementById('readScores')。innerHTML=allScores;
}**

在没有访问环境的情况下,最好使用firefox开发工具(或get firebug)在
saveScore
函数中设置断点。您可以在控制台窗口(REPL)中逐行检查当前范围内的值,甚至计算表达式

-使用firefox

-使用firebug(firefox插件)


如果你在做web开发,这些都是无价的资源,所以要花点时间学习如何使用它们。(它们会为你节省更多的时间!)

你考虑过JS闭包吗? 这里有一些东西给你一个想法

var scoreboard = (function () {
    var _privateVar = "some value"; //this is never exposed globally
    var _allScores = [];

    return {
        getAllScores: function() { //public
            return _allScores;
        },
        saveScore: function(value) { //public
            _allScores.push(value);
        }
    };
})();

alert(scoreboard.getAllScores().length); //0
scoreboard.saveScore(1);
alert(scoreboard.getAllScores().length); //1
alert(scoreboard._privateVar); //undefined
alert(scoreboard._allScores); //undefined

这样,您的变量和函数就永远不会暴露于窗口对象,您也不必担心重复项或作用域。唯一必须唯一的变量是闭包函数的名称(
scoreboard
,在本例中)

由于您在问题中提到了最佳实践,我对您的代码进行了重构,以展示一些可能对您和其他人将来有所帮助的实践。下面将列出此重构中使用的概念

var saveScore = (function () { /* Begin IIFE */
    /*
    The variables here are scoped to this function only.
    They are essentially private properties.
    */
    var MAX_ENTRIES = 3;

    /*
    Move the sorting function out of the scope of saveScore,
    since it does not need any of the variables inside,
    and possibly prevent a closure from being created every time
    that saveScore is executed, depending upon your interpreter.
    */
    function sorter(a, b) {
        return b - a;
    }

    /*
    As far as your example code shows, you don't appear to need the
    allScores variable around all the time, since you persist it
    to localStorage, so we have this loadScore function which
    pulls it from storage or returns a blank array.
    */
    function getScores() {
        var scores = localStorage.getItem('scores');
        return scores ? JSON.parse(scores) : [];
        /*
        Please note that JSON.parse *could* throw if "scores" is invalid JSON.
        This should only happen if a user alters their localStorage.
        */
    }

    function saveScore(score) {
        /* Implicitly load the scores from localStorage, if available. */
        var scores = getScores();

        /*
        Coerce the score into a number, if it isn't one already.
        There are a few ways of doing this, among them, Number(),
        parseInt(), and parseFloat(), each with their own behaviors.

        Using Number() will return NaN if the score does not explicitly
        conform to a textually-represented numeral.
        I.e., "300pt" is invalid.

        You could use parseInt(score, 10) to accept patterns
        such as "300pt" but not anything with
        leading non-numeric characters.
        */
        score = Number(score);

        /* If the score did not conform to specifications ... */
        if (isNaN(score)) {
            /*
            You could throw an error here or return false to indicate
            invalid input, depending on how critical the error may be
            and how it will be handled by the rest of the program.

            If this function will accept user input,
            it would be best to return a true or false value,
            but if a non-numeric value is a big problem in your
            program, an exception may be more appropriate.
            */

            // throw new Error('Score input was not a number.');
            // return false;
        }

        scores.push(score);
        scores.sort(sorter);

        /*
        From your code, it looks like you don't want more than 3 scores
        recorded, so we simplify the conditional here and move
        "magic numbers" to the header of the IIFE.
        */
        if (scores.length >= MAX_ENTRIES) {
            scores.length = MAX_ENTRIES;
        }
        /* Limiting an array is as simple as decreasing its length. */

        /* Save the scores at the end. */
        localStorage.setItem('scores', JSON.stringify(scores));

        /* Return true here, if you are using that style of error detection. */
        // return true;
    }

    /* Provide this inner function to the outer scope. */
    return saveScore;

}()); /* End IIFE */

/* Usage */
saveScore(prompt('Enter score.', ''));
正如您所看到的,在这个函数上下文中封装了分数处理逻辑,实际上没有任何东西可以在不使用接口的情况下篡改内部。从理论上讲,您的
saveScore
功能可以被其他代码取代,但是
iLife
的上下文内部只能对那些具有访问权限的代码进行更改。尽管还存在一些问题,但这种模块模式的方法提供了一个具有可预测结果的体面解决方案

  • ,一个立即调用的函数表达式,用于创建我们的模块
  • ,不要重复自己:代码重用
  • ,以及消除该等罪行
  • ,以及区分异常或返回代码的使用。相关:

您的代码还有改进的余地,但我看不到任何可能导致您描述的问题的地方。首先要检查的是,您的大型应用程序中是否有任何其他代码正在干扰
allScores
数组,因为它是全局的。顺便说一句,你真的需要它是全球性的吗?关于你的环境的更多信息会很有帮助,比如使用的是哪种浏览器或解释器,以及这些脚本是如何结合在一起的?@bfavaretto希望我的编码能随着我的技能的提高而提高。我认为它需要是全局的,因为我在将分数保存到数组时检查长度。我想我会得到前5名的分数。@Chip现在这个函数被一个onClick调用,询问用户是否想要保存分数。然后我使用getElementbyID将数组写入页面。我正在Firefox中以HTML5文档的形式进行测试。如果你真的想存储高分,在你的else块中,在你对高分进行排序后放入
allScores.pop()
。否则,你可以用一个较低的分数代替一个较高的分数。这非常感谢。我将彻底检查并复习你列出的所有术语。如果你找到了一个有用的答案,请随意投票。如果答案有助于你解决问题,你可以勾选复选标记来表明这一点。欢迎来到StackOverflow。因为我太新了,没有代表,所以还不能投票。我尝试了你的回答。将此标记为最有帮助的答案。尽管如此,我仍然需要根据自己的需要对其进行定制,我将其添加到了应用程序中,我的范围问题也得到了解决。我有一些关于你指针的阅读。再次感谢。