5.8 属性的访问
生成的对象可以通过属性来访问。对于对象的引用可以使用点运算符(.)或中括号运算符([])来访问其属性。需要注意的是,在点运算符之后书写的属性名会被认为是标识符,而中括号运算符内的则是被转为字符串值的式子。请看下面的例子:
var hzh1 = { x:3, y:4 }; console.log("输出hzh对象的x属性:"); console.log("hzh1.x = " + hzh1.x); // 属性x console.log("hzh1[x] = " + hzh1['x']); // 属性x var hzh2 = 'x'; console.log("hzh1[hzh2] = " + hzh1[hzh2]); // 属性x(而非属性key)
[Running] node "e:\HMV\JavaScript\JavaScript.js" 输出hzh对象的x属性: hzh1.x = 3 hzh1[x] = 3 hzh1[hzh2] = 3 [Done] exited with code=0 in 0.181 seconds
不过,对于对象字面量的属性名来说,下面这样的标识符或字符字面量形式的表示,都没问题。请注意不要与上面的规则混淆。
var hzh1 = 'x'; var hzh2 = { hzh1:3 }; // 属性hzh1(而非属性x) var hzh2 = { 'x':3 }; // 属性x
这里需要多提一句,属性访问的运算对象并不是变量,而是对象的引用。这一点,可以从以下直接 对对象字面量进行运算的示例中得到确认:
console.log("确认属性访问的运算对象是对象的引用:"); console.log({x:3, y:4}.x); // 属性x console.log({x:3, y:4}['x']); // 属性x
[Running] node "e:\HMV\JavaScript\JavaScript.js" 确认属性访问的运算对象是对象的引用: 3 3 [Done] exited with code=0 in 0.183 seconds
现实中几乎不会对对象字面量进行运算。不过当这种运算对象不是一个变量时,倒是常常会以方法链之类的形式出现。
5.8.1 属性值的更新
在赋值表达式的左侧书写属性访问表达式能够实现对属性值的改写。如果指定的是不存在的属性名,则会新增该属性。下面将不再使用右侧或左侧的说法,而改用属性读取,以及属性写入这样的术语。
可以使用 delete 运算表达式来删除属性。这里需要注意的是,很难区分不存在的属性与属性值为undefined 值的属性。
5.8.2 点运算符与中括号运算符在使用上的区别
有时选择用于访问对象属性的这两个运算符只凭偏好。点运算符的表述较为简洁,所以通常都会选用点运算符。不过,中括号运算符的通用性更高。
能使用点运算符的情况一定也可以使用中括号运算符,反之未必成立。但也无需因此全都使用中括号运算符。通常默认使用表述简洁的点运算符,只有在不得不使用中括号运算符的情况下,才使用中括号运算符。
只能使用中括号运算符的情况分为以下几种。
- 使用了不能作为标识符的属性名的情况。
- 将变量的值作为属性名使用的情况。
- 将表达式的求值结果作为属性名使用的情况。
包含数值或横杠(-)的字符串不能作为标识符使用。无法作为标识符使用的字符串,不能用于点运算符的属性名,且对于保留字,也有这样的限制。不过,原本就不应该将保留字作为属性名使用,所以这里不再赘述。
像下面这样,将含有横杠的属性名用于点运算符会引起错误。
// 含有横杠的属性名 var hzh = { 'huang-zihan':5 }; console.log(hzh.huang-zihan); // 将解释为hzh.huang减去zihan,从而造成错误
[Running] node "e:\HMV\JavaScript\JavaScript.js" e:\HMV\JavaScript\JavaScript.js:3 console.log(hzh.huang-zihan); // 将解释为hzh.huang减去zihan,从而造成错误 ^ ReferenceError: zihan is not defined at Object.<anonymous> (e:\HMV\JavaScript\JavaScript.js:3:23) at Module._compile (internal/modules/cjs/loader.js:999:30) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1027:10) at Module.load (internal/modules/cjs/loader.js:863:32) at Function.Module._load (internal/modules/cjs/loader.js:708:14) at Function.executeUserEntryPoint [as runMain] (internal/modules/run_main.js:60:12) at internal/main/run_main_module.js:17:47 [Done] exited with code=1 in 0.413 seconds
无法作为标识符被使用的字符串,仍可以在中括号运算符中使用。请看下面的例子,其中以字符串值指定了一个属性名。
// 含有横杠的属性名 var hzh = { 'huang-zihan':5 }; console.log(hzh['huang-zihan']); // 使用[]运算以字符串值指定了一个属性名。可以正常执行
[Running] node "e:\HMV\JavaScript\JavaScript.js" 5 [Done] exited with code=0 in 0.773 seconds
数值也是如此。数组对象的属性名都是数值。由于点运算符无法使用数值,因此只能使用中括号运算符。而且很多程序设计语言都是通过中括号运算符来访问数组的元素,所以可读性也随之提高。
下面的例子仍使用了之前的代码,用于展示将被变量的值作为属性名使用的情况。
var hzh1 = { x:3, y:4 }; console.log("输出hzh对象的x属性:"); console.log("hzh1.x = " + hzh1.x); // 属性x console.log("hzh1[x] = " + hzh1['x']); // 属性x var hzh2 = 'x'; console.log("hzh1[hzh2] = " + hzh1[hzh2]); // 属性x(而非属性key)
[Running] node "e:\HMV\JavaScript\JavaScript.js" 输出hzh对象的x属性: hzh1.x = 3 hzh1[x] = 3 hzh1[hzh2] = 3 [Done] exited with code=0 in 0.181 seconds
如果表达式的求值结果是字符串,可以直接用中括号运算符通过该表达式指定属性名。下面引用出自《JavaScript 语言精粹》一书的一个具有一定技巧性的例子。
这段代码会根据数值的符号而选择调用不同的方法。方法调用一词会让人觉得要使用的是点运算符,不过事实上中括号运算符也能被调用。
// 引用自《JavaScript语言精粹》一书 // 仅读取数值的整数部分的处理 Math[this < 0 ? 'ceiling' : 'floor'](this));
5.8.3 属性的枚举
可以通过 for in 语句对属性名进行枚举(代码清单 5.10)。通过在 for in 语句中使用中括号运算符,可以间接地实现对属性值的枚举。使用 for each in 语句可以直接枚举属性值。
代码清单 5.10 属性的枚举
var hzh1 = { x:'黄子涵是帅哥!', y:'黄子涵是靓仔!', z:'黄子涵真聪明!' }; for(var key in hzh1) { console.log('key = ', key); // 属性名的枚举 console.log('val = ', hzh1[key]); // 属性值的枚举 }
[Running] node "e:\HMV\JavaScript\JavaScript.js" key = x val = 黄子涵是帅哥! key = y val = 黄子涵是靓仔! key = z val = 黄子涵真聪明! [Done] exited with code=0 in 0.262 seconds
属性可以分为直接属性以及继承于原型的属性。for in 语句和 for each in 语句都会枚举继承于原型的属性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?