简体   繁体   English

如果key是RegExp的实例,则Object.keys效率不高

[英]Object.keys is not efficient if key is instance of RegExp

 let ob = {}; ob[/\\ing?$/] = `I match all strings end with "ing"`; //key is instance of 'RegEXp' ob["/\\ing?$/"] = `I am sure it is not same as the above`; //key is instance of 'String' console.log( `- Key RegExp : ==> ${ob[/\\ing?$/]} `); console.log( `- Key String : ==> ${ob["/\\ing?$/"]} `); 

The above string demonstrates that literal object property can be an instance of RegExp class and it can be also String of course and they are totally different . 上面的字符串表明文字对象属性可以是RegExp类的实例,当然也可以是String ,它们是完全不同的。

My question is how to check if the type property using Object.keys or alternative . 我的问题是如何使用Object.keys或Alternative检查类型属性。 Known that using Object.keys , this method casts all keys (properties) to string ? 已知使用Object.keys ,此方法将所有键(属性)强制转换为字符串?

Object.keys(ob);
 //--> Expected :[/\ing?$/, "/\ing?$/"]
 //--> Actual : ["/\ing?$/", "/ing?$/"]

Property names are always strings. 属性名称始终是字符串。 If you try to use something else as a property name, it will be converted to a string using toString() . 如果尝试使用其他名称作为属性名称,则将使用toString()将其转换为字符串。 So when you do: 因此,当您这样做时:

ob[/\ing?$/] = `I match all strings end with "ing"`; //key is instance of 'RegEXp';

it's treated as 它被视为

ob[/\ing?$/.toString()] = `I match all strings end with "ing"`; //key is instance of 'RegEXp';

So the key is "/\\ing?$/" . 所以键是"/\\ing?$/"

When you do: 当您这样做时:

ob["/\ing?$/"] = `I am sure it is not same as the above`; //key is instance of 'String';

the key is the string "/ing?$/" . 关键是字符串"/ing?$/" The backslash is gone because in a string literal, backslash is an escape character. 反斜杠消失了,因为在字符串文字中,反斜杠是转义字符。 \\i just escapes the i character, but since i has no special meaning, it's just i . \\i只是转义了i字符,但是由于i没有特殊含义,所以它就是i

If you wanted to get the same key as from the RegExp, it should be: 如果要从RegExp获取相同的密钥,则应为:

ob["/\\ing?$/"] = `I am sure it is not same as the above`; //key is instance of 'String';

The double backslash escapes the backslash, so it gets put into the string literally. 双反斜杠转义了反斜杠,因此将其按字面意义放入字符串中。

 let ob = {}; ob[/\\ing?$/] = `I match all strings end with "ing"`; //key is instance of 'RegEXp'; ob["/\\\\ing?$/"] = `I am sure it is not same as the above`; //key is instance of 'String'; console.log(ob); 

The above string demonstrates that literal object property can be an instance of RegExp class 上面的字符串说明文字对象属性可以是RegExp类的实例

That is wrong. 那是错的。 All object keys are string . 所有对象键都是string Anything that is not string will be converted to string. 非字符串的任何内容都将转换为字符串。 The proof can be seen in code sample below. 可以在下面的代码示例中看到该证明。 Although o1 and o2 are different, they both have same string representation and can be used to access the property of o . 尽管o1o2不同,但是它们都具有相同的字符串表示形式,并且可用于访问o的属性。

 var o1 = {}; o1.toString = function(){return "I am unique";}; var o2 = {}; o2.toString = function(){return "I am unique";}; var o = {}; o[o1] = "foo"; console.log(o[o2]); 

The properties are being converted to strings when they're set: 设置属性后,它们将被转换为字符串:

for (var key in ob) {
    console.log('key', key, 'type', typeof key);
}

> key /\ing?$/ type string
> key /ing?$/ type string

The RegExp at javascript at Question does not match the example string. RegExp javascriptRegExp与示例字符串不匹配。

 let re = /\\ing?$/; console.log(re.test(`I match all strings end with "ing"`)); 

You can use RegExp /(.|)ing?(\\1|\\.)$/ to match string ending with ing or ing. 您可以使用RegExp /(.|)ing?(\\1|\\.)$/匹配以inging.结尾的字符串ing. , or "ing" define property and value of object as RegExp "ing"将对象的属性和值定义为RegExp

 const re = /(.|)ing?(\\1|\\.)$/; let ob = {[re]:re}; console.log(ob[re].test(`I match all strings end with "ing"`)); console.log(ob[re].test(`I match all strings end with ing.`)); console.log(ob[re].test(`I match all strings end with ing`)); console.log(Object.getOwnPropertyDescriptors(ob)); for (let {[re]:regexp} of [ob]) { console.log(regexp instanceof RegExp); } 

Since I am the owner of question, The best solution that i noticed is to change the data structure from literal object to array : 由于我是问题的所有者,因此,我注意到的最佳解决方案是将数据结构从原义对象更改为array:

From : 来自:

ob = {
   /\ing?$/ : `I match all strings end with "ing"`,
  "/\ing?$/" : `I am sure it is not same as the above`
};

to : 至 :

ob = [

   {key: /\ing?$/ , value: `I match all strings end with "ing"` },
   {key:"/\ing?$/" , value: `I am sure it is not same as the above` },  
]

By that, we conserve the type of key if it is RegExp instance. 这样,如果它是RegExp实例,则可以保留键的类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM