替换对象(和/或数组)中的所有字符串实例 - JavaScript

时间:2014-04-13 19:13:38

标签: javascript string object replace

搜索未知深度和属性的JavaScript对象并替换给定字符串的所有实例的最佳方法是什么?

这样可行,但这是最好的方式吗?

var obj = {
   'a' : 'The fooman poured the drinks.',
   'b' : {
      'c' : 'Dogs say fook, but what does the fox say?'
   }
}

console.log (JSON.parse(JSON.stringify(obj).replace(/foo/g, 'bar')));

小提琴:http://jsfiddle.net/93Uf4/3/

1 个答案:

答案 0 :(得分:3)

除了你自己提出的方式之外,这里还有一个经典的循环方法。正如评论中的某些人所提到的那样,它更稳定,因为您不会冒险将对象拧紧并在尝试解析时抛出错误。另一方面,出现了一些问题(见下)。

但要小心,因为needle将用作正则表达式。您可以考虑为其添加某种quoting

我希望我没有忽视任何事情,所以要测试它并玩弄它。在这里你可以找到 fiddle

/**
  * Replaces all occurrences of needle (interpreted as a regular expression with replacement and returns the new object.
  * 
  * @param entity The object on which the replacements should be applied to
  * @param needle The search phrase (as a regular expression)
  * @param replacement Replacement value
  * @param affectsKeys[optional=true] Whether keys should be replaced
  * @param affectsValues[optional=true] Whether values should be replaced
  */
Object.replaceAll = function (entity, needle, replacement, affectsKeys, affectsValues) {
    affectsKeys = typeof affectsKeys === "undefined" ? true : affectsKeys;
    affectsValues = typeof affectsValues === "undefined" ? true : affectsValues;

    var newEntity = {},
        regExp = new RegExp( needle, 'g' );
    for( var property in entity ) {
        if( !entity.hasOwnProperty( property ) ) {
            continue;
        }

        var value = entity[property],
            newProperty = property;

        if( affectsKeys ) {
            newProperty = property.replace( regExp, replacement );
        }

        if( affectsValues ) {
            if( typeof value === "object" ) {
                value = Object.replaceAll( value, needle, replacement, affectsKeys, affectsValues );
            } else if( typeof value === "string" ) {
                value = value.replace( regExp, replacement );
            }
        }

        newEntity[newProperty] = value;
    }

    return newEntity;
};

最后两个参数是可选的,所以只需这样调用就可以了:

var replaced = Object.replaceAll( { fooman: "The dog is fooking" }, "foo", "bar" );

然而,仍然存在一些不清楚应该发生什么的边缘情况。例如:

// do you expect it to stay undefined or change type and become "undebazed"?
console.log( Object.replaceAll( { x: undefined }, "fin", "baz" ) );

// null or "nalala"?
console.log( Object.replaceAll( { x: null }, "ull", "alala" ) );

或者

// true or false?
console.log( Object.replaceAll( { x: true }, "true", "false" ) );

// true or "foo"?
console.log( Object.replaceAll( { x: true }, "true", "foo" ) );

数字相同

// 1337 or 1007?
console.log( Object.replaceAll( { x: 1337 }, "33", "00" ) );

// 1337 or "1foo7"
console.log( Object.replaceAll( { x: 1337 }, "33", "foo" ) );

我的方法当前没有处理这些情况 - 只会触及对象(用于嵌套)和字符串。