JS for...in循环内obj.key返回undefined而obj[key]正常的原因
JavaScript点访问与方括号访问属性的行为差异解释
两种写法表现不一致的根本原因,是JavaScript引擎对两种属性访问语法的解析规则完全不同:
- 点号访问语法(
obj.propName):点号后方的内容是固定字面量属性名,引擎不会将其作为变量求值,只会直接查找对象上名称和该字面量完全一致的属性。 - 方括号访问语法(
obj[expr]):方括号内部是可执行的表达式,引擎会先对表达式求值,再将求值得到的结果作为目标属性名,去对象上查找对应属性。
对应示例的行为拆解
我们逐段分析给出代码的执行逻辑:
let obj = { name: "lucky", hobbies: "coding" } console.log(obj.name) for (let key in obj) { console.log(obj.key) }
- 循环外执行
obj.name时,点号后是字面量name,和对象上定义的name属性完全匹配,因此正常输出属性值lucky。 - for...in循环遍历对象时,声明的变量
key会依次被赋值为遍历到的属性名字符串:第一轮值为"name",第二轮值为"hobbies"。 - 循环内写
obj.key时,按照点访问的解析规则,引擎会直接查找对象上名称就叫key的属性——但示例中的obj只定义了name、hobbies两个属性,不存在名为key的属性,因此两次访问都返回undefined,和实际运行输出一致。 - 如果将循环内的写法替换为
obj[key],引擎会先读取变量key存储的字符串值:第一轮等价于obj["name"],第二轮等价于obj["hobbies"],就能正常拿到两个属性的对应值。
补充说明
点访问本质是方括号访问的特殊语法糖:obj.name和obj["name"]的执行效果完全一致。只有当目标属性名是固定字符串、且符合JavaScript标识符命名规范时,才可以使用点写法;如果属性名存储在变量中、属性名包含特殊字符(比如空格、连字符)、或者属性名是Symbol类型,都必须使用方括号写法访问。
内容的提问来源于stack exchange,提问作者lucky
相关产品推荐
相关产品推荐

