JavaScript中的对象概念非常不同,要把它当作其它语言的关联数组(如PHP)或者Map(如Java)来理解的话,还是有很大的不一样——由于原型链和属性描述符(主要是[[Enumerable]])的存在。
一个对象字面量{}有Object作为原型,它有继承自原型链的不可枚举的toString方法。下面将以对象字面量为例。
-
下标操作符、点操作符可以访问到自身属性或继承自原型链的任何属性,除非出现了属性覆盖
var a ={}; a.toString返回toString方法
var a ={toString:"a"}; a.toString返回字符串"a" -
for in循环将枚举的自身属性和继承自原型链的所有[[Enumerable]]的属性 -
"key" in obj的判断中,判断自身属性或继承自原型链的属性的存在性
"toString" in {}返回true -
obj.hasOwnProperty()的判断中,只判断自身属性的存在性
({}).hasOwnProperty("toString")返回false
({toString:"a"}).hasOwnProperty("toString")返回true -
Object.keys()可返回自身[[Enumerable]]的属性组成的数组,不包括原型链上继承的属性
Object.keys({a:1})返回["a"],不包含原型链上的toString等内容 -
Object.getOwnPropertyNames()可以返回自身任何属性组成的数组,不包括原型链上继承的属性
| 类目 | 语句 | 自身属性 | 原型链上继承的属性 | ||
| 可枚举属性 | 不可枚举属性 | 可枚举属性 | 不可枚举属性 | ||
| 访问 | obj.prop | √ | √ | √ | √ |
| obj["prop"] | √ | √ | √ | √ | |
| 循环 | for key in obj | √ | √ | ||
| 判断 | key in obj | TRUE | TRUE | TRUE | TRUE |
| obj.hasOwnProperty(key) | TRUE | TRUE | FALSE | FALSE | |
| 列举 | Object.keys(obj) | √ | |||
| Object.getOwnPropertyNames(obj) | √ | √ | |||
可以通过以下方式避免遍历过程中的原型链干扰:
- 在get/set方法中为每一个键加上前缀
Object.create(null)来创建一个没有原型的对象
这些都可以在StringMap的解决方案里找到。
本文深入探讨了JavaScript中对象的概念及其与关联数组或Map的差异,解释了下标操作符、点操作符如何访问对象属性,以及如何通过forin循环、hasOwnProperty()和Object.keys()、Object.getOwnPropertyNames()进行属性枚举。
273

被折叠的 条评论
为什么被折叠?



