0

我正在使用Javascript 中的 Dictionary Lookups 中详细描述的一种方法(请参阅“客户端解决方案”部分)来创建一个对象,该对象包含拼字游戏字典中每个单词的属性。

var dict = {};

//ajax call to read dictionary.txt file
$.get("dictionary.txt", parseResults);


function parseResults(txt) {
var words = txt.split( "\n");

  for (var i=0; i < words.length; i++){
      dict[ words[i] ] = true;
  }

  console.log(dict.AAH);
  console.log(dict);

  if (dict.AAH == true) {
     console.log('dict.AAH is true!');
  }


}

(更新代码以使用 Phil 的较早答案)

我不知道为什么 dict.AAH 返回未定义,但 dict 对象在控制台中看起来不错。下面是 Firebug 的截图。

安慰:

安慰

深入到“对象{}”

目的

我如何检查给定的单词(在这种情况下为“AAH”),如果它是 dict 对象中定义为 true 的属性,则让它返回 true?

4

5 回答 5

1

这可能是一个比赛条件。您正在将字典加载到 a 中GET,然后立即(在发出请求时)调用这些 console.log 命令(并且返回未定义的命令)。然后在您调试时实际加载数据。一切都应该在回调或延迟中完成。这是调试器的一个可以理解的怪癖,它让我之前遇到过。

于 2012-09-15T17:10:28.950 回答
1

您正在尝试在成功处理程序dict填充它之前进行输出。$.get

试试这个:

// If the browser doesn't have String.trim() available, add it...
if (!String.prototype.trim) {
    String.prototype.trim=function(){return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');};

    String.prototype.ltrim=function(){return this.replace(/^\s+/,'');};

    String.prototype.rtrim=function(){return this.replace(/\s+$/,'');};

    String.prototype.fulltrim=function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' ');};
}

/**
 * Parses the response returned by the AJAX call
 *
 * Response parsing logic must be executed only after the
 * response has been received. To do so, we have to encapsulate
 * it in a function and use it as a onSuccess callback when we
 * place our AJAX call.
 **/
function parseResults(txt) {
    // clean the words when we split the txt
    var words = txt.split("\n").map($.trim);

    for (var i=0; i < words.length; i++){
        dict[ words[i] ] = true;
    }

    console.log(dict.AAH);
    console.log(dict);

    if (dict.AAH == true) {
       console.log('dict.AAH is true!');
    }
}

// global object containing retrieved words.
var dict = {};

//ajax call to read dictionary.txt file
$.get("dictionary.txt", parseResults);

正如另一位用户评论的那样,jQuery 的$.when允许您链接此类代码。

顺便说一句,如果您只想知道结果中是否有单词,您可以这样做:

function parseResults(txt) {
    // clean the words when we split the txt
    var words = txt.split("\n").map($.trim);

    if ($.inArray('AAH', words)) {
        console.log('AAH is in the result set');
    }
}
于 2012-09-15T17:11:42.797 回答
1

获取 ajax 请求是异步的。这意味着当 ajax 请求中发生的整个操作正在进行时,javascript 会继续读取下一行。

那么问题是您正在记录 ajax 请求未能足够早地检索到的值。

要解决此问题,您可以在 ajax 请求回调中包含日志调用,如下所示

var dict = {};

//ajax call to read dictionary.txt file
$.get("dictionary.txt", function( txt ){
    var words = txt.split( "\n");

    for (var i=0; i < words.length; i++){
        dict[ words[i] ] = true;
    }

    //Now inside these console.log will run once you DO have the data
    console.log(dict.AAH);
    console.log(dict);
});

//不管异步请求是否完成,这里的东西都会运行

对于这种类型的场景,我更建议在 JQuery 中使用 WHEN 方法作为最佳解决方案

以下是我认为最适合复杂项目的方式

var dict = {};

//ajax call to read dictionary.txt file
function getDictionary(){
    return $.ajax("dictionary.txt");
}

/*I recommend this technique because this will allow you to easily extend your 
code to maybe way for more than one ajax request in the future. You can stack 
as many asynchronous operations as you want inside the when statement*/

$.when(getDictionary()).then(function(txt){//Added txt here...forgot callback param before

   var words = txt.split( "\n");

    for (var i=0; i < words.length; i++){
        dict[ words[i] ] = true;
    }

    //Now inside these console.log will run once you DO have the data
    console.log(dict.AAH);
    console.log(dict);
});
于 2012-09-15T17:35:55.380 回答
1

问题不在于您的代码。你的话里有看不见的字符,你没有清理干净。

您可以通过将其用作结果解析器来验证这一点

function parseResults(txt) {
  // clean the words when we split the txt
  var words = txt.split("\n")
                 .map($.trim)
                 .splice(0,3); // Keep only 3 first ones

  if(btoa(words[2]) !== btoa('AAH')){ // Compare in Base64
    console.log('YOU HAVE HIDDEN CHARS!');
  }

}

你可以通过将你的角色列入白名单来修复它。

function parseResults(txt) {
  // clean the words when we split the txt
  var words = txt.split("\n").map(function(el){
    return el.match(/[a-zA-Z0-9]/g).join('');
  });

  for (var i=0; i < words.length; i++){
      dict[ words[i] ] = true;
  }

  console.log(dict.AAH);
  console.log(dict);

  if (dict.AAH == true) {
     console.log('dict.AAH is true!');
  }
}

我建议在服务器端清理它,因为在与您的实时站点中看到的一样大的数组中的每个元素上运行正则表达式可能会导致性能问题。

于 2012-09-26T16:51:00.680 回答
0

我认为问题在于您已将dict其定义为对象,但将其用作数组。

替换var dict = {}var dict = new Array(),您的代码应该可以工作(尝试在 Google Chrome 上使用您的实时示例)。

于 2012-09-26T13:41:56.710 回答