【问题标题】:Using string "constructor" as key in JavaScript object在 JavaScript 对象中使用字符串“构造函数”作为键
【发布时间】:2014-07-06 03:42:58
【问题描述】:

我正在做一个 Exercism JavaScript 练习,但我遇到了困难。练习是创建一个循环遍历字符串的函数,然后创建一个对象,其中每个单词作为键,该单词出现的次数作为相应的值。简单吧?好吧,现在我被困在后面的步骤之一,输入字符串包含单词“constructor”,您需要将它作为键放入对象中。这是我到目前为止的代码,以及测试它的 Jasmine 规范:

function words(words){
    count = {};
    splits = words.split(" ");
    for(var i = 0; i < splits.length; i++){
        splits[i] = splits[i].replace(/[;:!&@$%\^,]/g, "").toLowerCase();
        if([splits[i]] == ""){
            continue;
        }else if(count[splits.i] !== null){
            count[splits[i]]++;
        }else{
            count[splits[i]] = 1;
        }
    }
    return count;
};

words("constructor Constructor")

describe("words()", function() {
  it("counts constructor", function() {
    var expectedCounts = { constructor: 2 };
    expect(words("constructor Constructor")).toEqual(expectedCounts);
  });
});

问题是,在第二个条件中使用点或括号表示法,它的计算结果为 true,因为“构造函数”是从链上的 Object 原型继承的,因此它会尝试增加 NaN 值。我试图找到一个解决方法,但结果是空的。尽管我很喜欢 JS,但它的继承也有它的怪癖。在这种情况下是否有任何方法可以防止继承或其他任何人都可以想到的解决方法?

【问题讨论】:

  • constructor 不是你最大的问题。 count[splits.i] !== null 这条线很时髦。而且它不会像你想要的那样工作,因为这种情况永远不会是false。如果将其更改为typeof counts[splits[i]] === 'number',它应该可以正常工作。如果你想要一个不继承任何东西的对象,你可以使用Object.create(null)
  • 避免与对象上已有的现有键发生冲突的一种方法是在添加键或测试键是否存在时添加的任何键前添加"_"。额外的开销,但本质上为您提供了您自己的密钥命名空间。迭代键时,使用.hasOwnProperty() 避免预先存在的键。
  • count[splits.i] !== null 如果对象中已经没有键,则将评估为 true,因此它会创建要启动的键并将其 val 设置为 1。到目前为止它已经工作了,但是我喜欢使用 typeof count[splits.i] === 'number'。问题是这是评估未定义所以没有进展,除非我错过了什么。

标签: javascript inheritance constructor jasmine prototype


【解决方案1】:

不要与null 比较来查看您是否已经在count 上设置了属性,而是使用hasOwnPropertyhasOwnProperty 不包括来自原型链的属性,只包括直接在对象上的属性。

if (count.hasOwnProperty(splits[i])) {
    count[splits[i]]++;
} else{
    count[splits[i]] = 1;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 2015-11-07
    • 1970-01-01
    相关资源
    最近更新 更多