mat*_*ots 4 javascript ecmascript-5 ecmascript-6
我遇到过这篇文章,建议如果你的密钥总是字符串,那么就需要使用'裸对象'来满足你的hashmap.
裸对象是使用null原型值创建的对象,例如Object.create(null).使用对象文字符号(即{})不会创建裸对象,因为它们被设置Object.prototype为原型.
文章指出裸机对象的优点是你可以将它们用作哈希映射,而不必担心内置键,比如toString在使用同名密钥时可能会导致错误.
这种行为是ES5和/或ES6标准的一部分吗?也就是说,如果我在代码中使用裸对象作为字符串键哈希映射,我可以依赖我的代码以我期望的方式运行吗?这里有什么警告吗?
首先,ECMA-Script 2015及以上版本的集合如Map.也就是说,在较新的JavaScript实现中,您不再需要使用对象模拟字典/ hashmaps/hashtables.
文章指出裸机对象的优点是你可以将它们用作哈希映射,而不必担心内置键,如toString,当使用同名的键时可能会导致错误.
文章忽略了你不需要担心toString文字对象,因为有很好的支持函数来获取自己的对象的属性而不需要遍历原型链.
例如,假设我已经声明了一个文字对象,如下所示:var obj = { text: "Matias" };.
常规for..in循环将迭代Object.prototype属性,但仅Object.keys迭代自己的对象属性:
Object.keys(obj).forEach(propertyName => {
var someOwnProperty = obj[propertyName ];
});
Run Code Online (Sandbox Code Playgroud)
此外,常规for..in可以Object.keys使用Object.prototype.hasOwnProperty:
for(var propertyName in obj) {
if(obj.hasOwnProperty(propertyName)) {
// True if property is declared on obj and not in some
// level of the prototype chain
}
}
Run Code Online (Sandbox Code Playgroud)
最新消息: @bergi对某事是正确的.如果obj要声明一个自己的财产hasOwnProperty,上面for..in就不会有效,因为obj.hasOwnProperty不再存在Object.prototype.hasOwnProperty了.
想象一下,您有以下会产生上述问题的对象:
var obj = {
hasOwnProperty: "hey! I'm not Object.prototype.hasOwnProperty anymore!"
};
Run Code Online (Sandbox Code Playgroud)
那hasOwnProperty会隐藏Object.prototype.hasOwnProperty.
上述问题可以Object.prototype.hasOwnProperty直接使用Function.prototype.call:
for(var propertyName in obj) {
if(Object.prototype.hasOwnProperty.call(obj, propertyName)) {
// True if property is declared on obj and not in some
// level of the prototype chain
}
}
Run Code Online (Sandbox Code Playgroud)
或者您可以存储Object.prototype.hasOwnProperty在变量中以简化if语句设置,this一旦函数被调用,将会是什么Function.prototype.bind:
var hasOwnProperty = Object.prototype.hasOwnProperty.bind(obj);
for(var propertyName in obj) {
if(hasOwnProperty(propertyName)) {
// True if property is declared on obj and not in some
// level of the prototype chain
}
}
Run Code Online (Sandbox Code Playgroud)
虽然您可以创建裸对象有Object.create(null),问题是当一个给定的裸对象是一些其他对象的原型:
var bareObject = Object.create(null, {
text: { value: "hello world" }
});
var secondObject = Object.create(bareObject);
secondObject.text2 = "bye!";
for(var property in secondObject) {
// WAIT, secondObject prototype is a bare object!
// And I can't call secondObject.hasOwnProperty to check
// if the enumerated property is declared in the own object...
}
Run Code Online (Sandbox Code Playgroud)
如果不是这种情况并且给定对象只是一个裸对象,则可以使用in运算符:
if("someProperty" in bareObject) {
}
Run Code Online (Sandbox Code Playgroud)
否则,你需要在我的回答中Object.prototype.hasOwnProperty使用Function.prototype.call或Function.prototype.bind如上所述.
无论如何,正如我在答案的开头所说,如果您正在使用ES2015及更高版本,并且您正在使用像BabelJS这样的转换器,您可以使用新的JavaScript标准集合类型,而不是使用对象模拟字典.
这种行为是ES5和/或ES6标准的一部分吗?也就是说,如果我在代码中使用裸对象作为字符串键哈希映射,我可以依赖我的代码以我期望的方式运行吗?这里有什么警告吗?
Object.create 在ECMA-Script 5中引入了它.它几乎可以在任何现代Web浏览器和NodeJS中运行.