我更喜欢使用Object.create(null),这样我就可以将对象用作简单的字典来存储基本信息.如果我需要对象功能,那么我会创建一个普通对象,例如var obj = {x:3, etc};
这是因为{}并不是真正的空白对象,因为它链接到Object原型,所以在循环中你必须做的hasOwnProperty是阻止它在原型链周围跳舞,并且对每个循环进行检查会阻碍性能,尽管它可以忽略不计.
使用Object.create(null)而不是不好的做法{},所以我不必hasOwnProperty在每个循环中写入?
编辑:可能重复,但我不是问他们是如何或为什么他们不同,而是我有兴趣知道其他人是否使用Object.create(null)?在Javascript中是SOP吗?
编辑2:我也更喜欢进行单行检查,例如if(obj[someKey])...ht'Tribute to APJ Kalam Sir'.
小智 34
如果不继承Object.prototype与Object.create(null)您的对象不再对对象原型的方法.所以显而易见的问题是,该原型的方法是什么,你需要它们吗?
方法是:
hasOwnPropertyisPrototypeOfpropertyIsEnumerabletoString/toLocaleStringvalueOfhasOwnProperty似乎没什么用处,因为如果没有原型,创建对象上的所有属性都是定义自己的属性.但是,可以想象一些库或其他代码可能会for...in使用if (o.hasOwnProperty(key))习惯用法迭代对象的属性.希望它能使用更正确的东西可能太过分了Object.prototype.hasOwnProperty.call(o, key).这样的代码现在会失败.或者,您可能正在创建一个以创建的对象为原型的子对象,并且有兴趣知道属性是属于子对象的属性还是来自原型.
isPrototypeOf 如果您计划将创建的对象用作其他对象的原型,则可能会或可能不会有用,并且出于某种原因想要检查所创建的对象是否在此类其他对象的原型链中.
propertyIsEnumerable不会使用太多,但是再一次,我们无法预测系统中的其他代码将会做什么.如果它试图在创建的对象上调用此方法,或者使用它创建的任何对象作为原型,它将失败.
这同样适用toString.谁知道谁可能试图在你创建的对象上调用它?例如,某些库可能会尝试通过执行a toString并查看结果是否来测试值的类型"[object Object]".希望他们安全Object.prototype.toString.call(o),但......
valueOf很少显式使用,但如果它需要将对象强制转换为基元,则由引擎调用.如果缺少,代码可能会破坏:
> o2 = Object.create(null)
> o2 + 1
Uncaught TypeError: Cannot convert object to primitive value
Run Code Online (Sandbox Code Playgroud)
当然,也有可能有人为Object原型添加了方法,在这种情况下Object.create({})会将它们捡起来.可能你不想要或不需要它们.另一方面,它们很可能是无害的.
鉴于所有这些,似乎Object.create(null)应该限于特定情况,证明上述问题都不会发生.例如,对象永远不会传递到其本地上下文之外,或者永远不会被用作另一个对象的原型.即使在这种情况下,性能优势也将非常小,甚至为零.
我有兴趣知道其他人是否使用
Object.create(null)?是JavaScript中的SOP吗?
我不认为它可以被称为SOP.
Dip*_*ole 19
尽我所知,
{} == Object.create(Object.prototype);
Run Code Online (Sandbox Code Playgroud)
也,
对我来说(只有我)我想让Object.create(null)你更清楚你的对象不会继承任何东西,即its (purely) empty map.
也,
在这两种情况下,您都可以将对象用作字典.
也,
这取决于你应该对你的对象做什么.
什么时候,
{} == Object.create(Object.prototype); //你继承了所有的对象属性
o = Object.create(null);//你没有继承任何东西.这是完全空白的对象.
如果您使用对象作为地图,并使用上面的方法1创建对象,那么在地图中进行查找时必须格外小心.由于继承了Object中的属性和方法,因此您的代码可能会遇到地图中有从未插入的键的情况.
例如,如果你对toString进行了查找,你会找到一个函数,即使你从未在那里放过那个值.你可以像这样解决这个问题:
if (Object.prototype.hasOwnProperty.call(object, 'toString')) {
// we actually inserted a 'toString' key into object
}
Run Code Online (Sandbox Code Playgroud)
请注意,您不能只执行object.hasOwnProperty('toString'),因为您可能已将一个键"hasOwnProperty"插入到对象中,因此我们强制它使用Object中的实现.
另一方面,如果您使用上面的方法2,那么您将不必担心地图中出现的对象.
你不能检查是否存在一个简单的属性,如下所示:
// Unreliable:
if (object[someKey]) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
所以,
要将对象用作地图,大多数地球上的人都会使用它
Object.create(null) //无需担心继承属性的开销.
在其他所有情况下,你只需使用,
var myObject = {}
小智 7
我想参考 Mozilla 文档中关于Objects and maps 的比较,让Map有机会成为现在更好的实践。
Objects类似于Maps两者都允许您将键设置为值、检索这些值、删除键以及检测某个键是否存储了某些内容。正因为如此(并且因为没有内置的替代品),Objects在Maps历史上被用作; 但是,在某些情况下使用 a 的Map重要区别是:
- an 的键
Object是字符串和符号,而它们可以是 a 的任何值Map,包括函数、对象和任何原语。- 您可以
Map使用 size 属性轻松获取 a的大小,而 an 中的属性数量Object必须手动确定。- A
Map是可迭代的,因此可以直接迭代,而迭代 anObject需要以某种方式获取其键并对其进行迭代。- An
Object有一个原型,所以如果你不小心,地图中有默认的键可能会与你的键发生冲突。从 ES5 开始,这可以通过使用 绕过map = Object.create(null),但很少这样做。- A
Map在涉及频繁添加和删除密钥对的场景中可能表现更好。
您是说Object.create(null)当您想要创建一个不继承自 的对象Object.prototype时,您正在使用 for 。
这正是将Object.create方法null作为第一个参数的用例。
使用{}相当于Object.create(Object.prototype). 很多时候我们想要这样做,这就是为什么它是字面量所做的,但在您的情况下,您对继承的控制更清晰。
如果您需要任何方法Object.prototype,您可以使用.call或.apply在您的对象上调用,
var o = Object.create(null);
Object.prototype.hasOwnProperty.call(o, 'foo'); // some key foo
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6239 次 |
| 最近记录: |