【问题标题】:Javascript reserved word and objectJavascript 保留字和对象
【发布时间】:2018-04-10 23:05:10
【问题描述】:

我正在制作一个单词词典,所以有 1,000,000 多个单词。 当我需要存储单词constructor 时,问题就来了。我知道这是 javascript 中的保留字,但我需要将其添加到字典中。

var dictionary = {} 
console.log(dictionary ['word_1']) 
//undefined, this is good
console.log(dictionary ['word_2']) 
//undefined, this is good
console.log(dictionary ['constructor']) 
//[Function: Object] 
// this cause initialization code to break

我该如何解决这个问题?我可以像key=key+"_" 那样处理它,但这似乎很糟糕。还有什么我可以做的吗?

【问题讨论】:

  • 将这些词存储为对象属性对我来说似乎不是一个好主意。也许您可以考虑的是这些词的数组:['word_1', 'word_2', ...],或者如果您需要更多信息以及每个词:[{word: 'word_1', anotherProperty: '...'}, ...]
  • 如果属性设置在给定对象上,您将始终必须使用hasOwnProperty 来检查是否可靠。
  • 问题不在于constructor 是保留字,而在于对象继承了constructor 属性。 (在更一般的意义上,创建保留字的对象属性名称没有问题。)
  • @nnnnnn 谢谢,是的,你明白问题所在。我可以做些什么来解决它吗?
  • 如果您想测试该属性是否直接存在于对象上,请使用.hasOwnProperty(),正如 t.niesse 已经提到的那样。

标签: javascript javascript-objects reserved-words


【解决方案1】:

constructor 键覆盖为undefined

根据the MDN Object.prototype page,唯一未被__fieldname__ 架构隐藏的是“构造函数字段”。因此,您可以通过 { 'constructor': undefined } 初始化您的对象。

但是,您必须确保在您的 for .. in 语句中过滤掉所有以 undefined 为值的键,因为它会将 constructor 作为“有效”键(即使它不会'在您专门将其设置为未定义之前)。即。

for(var key in obj) if(obj[key] !== undefined) { /* do things */ }

获取/设置时检查类型

否则,您可以在“获取”或“存储”它时检查类型。即。

function get(obj, key) {
  if(typeof obj[key] !== 'function') // optionally, `&& typeof obj[key] !== 'object')`
    return obj[key];
  else
    return undefined;
}

【讨论】:

    【解决方案2】:

    我认为您应该将所有单词及其翻译存储在一个数组中。当需要翻译一个单词时,可以使用Array的find方法。

    例如:

    var dict = [
        { word: "abc", translated: "xyz" },
        ...
    ];
    

    然后:

    var searching_word = "abc";
    var translation = dict.find(function (item) {
        return item.word == searching_word;
    });
    console.log(translation.translated);
    // --> xyz
    

    【讨论】:

    • OP 在哪里提到翻译?
    • 另外,200k 字的速度可能太慢了
    • 因为每个 JS 数据类型都有一些原生方法,所以不能全部覆盖。或者您可以在将每个单词存储在对象中时以“@”开头,以与其他本地方法名称区分开来。
    • @QuyetTran 使用前缀只是一种技巧,将来可能会失败。例如使用@@ 为特殊键添加前缀,如可迭代。
    【解决方案3】:

    您可以使用内置的Map 类型而不是使用 JS 对象,该类型使用字符串/符号作为键并且不与任何现有属性冲突。

    替换 var dictionary = {}var dictionary = new Map()

    【讨论】:

    • 同意,地图是您使用的更好选择。试试看:new Map().set('constructor', 'bbb').get('constructor')Mozilla dev link
    【解决方案4】:

    要达到预期的效果,请使用以下使用索引的选项来获取任何键值的值

    var dictionary = {};
    
    var dictionary1 = {
      constructor: "test"
    };
    
    //simple function to get key value using index
    function getVal(obj, val) {
      var keys = Object.keys(obj);
      var index = keys.indexOf(val);//get index of key, in our case -contructor
      return obj[keys[index]]; // return value using indec of that key
    }
    
    console.log(getVal(dictionary, "constructor"));//undefined as expected
    console.log(getVal(dictionary1, "constructor"));//test
    
    console.log(dictionary["word_1"]);
    //undefined, this is good
    console.log(dictionary["word_2"]);
    //undefined, this is good
    

    codepen - https://codepen.io/nagasai/pen/LOEGxM

    为了测试,我给了一个带有键构造函数的对象和另一个没有构造函数的对象。

    基本上我首先获取键的索引并使用索引获取值

    【讨论】:

    • .hasOwnProperty() 不是测试对象是否具有特定自身属性的更明显的方法吗?使用数组.indexOf() 来查找对象属性似乎非常低效。此外,如果没有匹配val 的属性,您的getVal() 函数将尝试从键名为"undefined" 的属性中返回值,考虑到他们正在创建字典,该值可能实际上存在于OP 的对象中一百万字。 (另外,为什么要调用Object.keys(obj) 两次而不是将结果放入变量中?)
    • 谢谢@nnnnnn,我已经更新了我的答案,我只是提供了我的选项作为一种解决方法,正如你所说的 hasOwnProperty() 也可以,但有人已经提到过,所以我只是把这个答案作为一个选项.and with hasOwnProperty OP 可以找到 obj 是否有键,并且在使用构造函数关键字获取值时,他会以同样的问题结束
    猜你喜欢
    • 2014-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-01
    • 2014-12-24
    • 2017-08-26
    相关资源
    最近更新 更多