How to use a RegExp literal as object key?

前端 未结 4 2019
野的像风
野的像风 2020-12-13 18:34

I would like to use create a object that contains regular expressions as the key value. I tried to use the following syntax:

var kv = {
    /key/g : \"value\         


        
相关标签:
4条回答
  • 2020-12-13 18:48

    Object keys cannot be RegExp objects. You must use a string or a valid ID. That being said, you could do something like this:

    var kv = {
        "/key/g": "value"
    };
    

    I'm curious. Why do you want to do this?

    EDIT: I am partially mistaken. RegExp objects can be used as keys, but not using the object literal syntax. See jmar777's answer.

    0 讨论(0)
  • 2020-12-13 18:49

    You can also use an expression as a key by wrapping it in [] when creating an object:

    var kv = {
        [/key/g] : "value"
    };
    
    0 讨论(0)
  • 2020-12-13 18:54

    This can be done, but not using object literal syntax. You'll need to do it like this:

    var kv = {};
    kv[/key/g] = "value";
    console.log(kv[/key/g]); // "value"
    


    Edit: this could probably use some explaining. As xanatos commented below, what's really happening here is that the key, /key/g in this case, is being toString()'d to create the key. This is important to know, because it has an effect on key uniqueness. Consider the following:

    var x = {},
        reg = /foo/;
    
    x[reg] = 'bar';
    console.log(x[reg]); // "bar"
    console.log(x[reg.toString()]); // "bar"
    console.log(x['/foo/']); // "bar'
    

    In summary, I'm semi-scared to ask why you need to do this, but assuming you have your reasons, be careful and make sure you understand what is really happening :)


    Edit 2: So in response to your updated question, you should be able to achieve something pretty close to what you want. You can use the object literal syntax as long as you wrap the regular expression in quotes. Unfortunately that means you'll have to manually reconstruct an actually RegExp object out of that key though. For example:

    var result = "abcdef",
        replacements = {
            "/a/g": "FOO",
            "/d/i": "BAR"
        };
    
    for (var key in replacements) {
        var parts = key.split('/');
        result = result.replace(new RegExp(parts[1], parts[2]), replacements[key]);
    }
    
    console.log(result); //FOObcBARef
    


    Edit 3: Because, why not. I was so stuck on making your object-literal syntax work, that I didn't consider the fact that you never need to actually look up the replacement by the pattern itself (i.e., there's no need for object keys at all). Here's a more efficient approach using arrays that doesn't require the RegExp reconstruction:

    var result = "abcdef",
        replacements = [
            [/a/g, "FOO"],
            [/d/i, "BAR"]
        ];
    
    for (var i = 0, len = replacements.length; i < len; i++) {
        var replacement = replacements[i];
        result = result.replace(replacement[0], replacement[1]);
    }
    
    console.log(result); //FOObcBARef
    


    Edit 4: Because I'm bored and I like this question. Here's the ninja version:

    var result = "abcdef",
        replacements = [
            [/a/g, "FOO"],
            [/d/i, "BAR"]
        ], r;
    
    while ((r = replacements.shift()) && (result = String.prototype.replace.apply(result, r))) {}
    
    console.log(result); //FOObcBARef
    
    0 讨论(0)
  • 2020-12-13 19:09

    I think this question deserves an updated answer. Since ES6, a new type (standard built-in object) called Map was created to cover cases like this one among others.

    A Map is very similar to an Object, except it allows any type as key.

    Map.prototype.forEach() can then be used to loop over each key/value pair.

    In your case, your function could now be:

    function fixUnicode(text) {
    
        var result = text;
        var replaceMap = new Map();
        replaceMap.set(/&Atilde;&copy;/g, "&eacute;");
        replaceMap.set(/&Atilde;&uml;/g, "&egrave;");
        replaceMap.set(/&Atilde;&ordf;/g, "&ecirc;");
        replaceMap.set(/&Atilde;&laquo;/g, "&euml;");
        replaceMap.set(/&Atilde;&nbsp;/g, "&agrave;");
        replaceMap.set(/&Atilde;&curren;/g, "&auml;");
        replaceMap.set(/&Atilde;&cent;/g, "&acirc;");
        replaceMap.set(/&Atilde;&sup1;/g, "&ugrave;");
        replaceMap.set(/&Atilde;&raquo;/g, "&ucirc;");
        replaceMap.set(/&Atilde;&frac14;/g, "&uuml;");
        replaceMap.set(/&Atilde;&acute;/g, "&ocirc;");
        replaceMap.set(/&Atilde;&para;/g, "&ouml;");
        replaceMap.set(/&Atilde;&reg;/g, "&icirc;");
        replaceMap.set(/&Atilde;&macr;/g, "&iuml;");
        replaceMap.set(/&Atilde;&sect;/g, "&ccedil;");
    
        replaceMap.forEach(function (newString, old) {
          result = result.replace(old, newString);
        });
    
        return result;
    }
    

    You can read more about maps at MDN

    0 讨论(0)
提交回复
热议问题