- 简略来说,对象就是一组“键值对”(key-value)的汇合
var obj = { foo: 'Hello', bar: 'World'};
下面代码中,大括号就定义了一个对象,它被赋值给变量obj
,所以变量obj
就指向一个对象。该对象外部蕴含两个键值对(又称为两个“成员”),第一个键值对是foo: 'Hello'
,其中foo
是“键名”(成员的名称),字符串Hello
是“键值”(成员的值)。键名与键值之间用冒号分隔。第二个键值对是bar: 'World'
,bar
是键名,World
是键值。两个键值对之间用逗号分隔。
- 值得注意的是,对象的所有键名都是字符串,加不加引号都能够。若键名是数值,也会被主动转化为字符串
var obj = { 1: 'a', 3.2: 'b', 1e2: true, 1e-2: true, .234: true, 0xFF: true};
然而,若键名不合乎标识名的条件,且不是数字,则必须加上引号,否则会报错
var obj = { '1p': 'Hello World', 'h w': 'Hello World', 'p+q': 'Hello World'};
- 键名又称为属性,其键值能够为数据类型。
(1)若键值为函数,则把此属性称为办法
(2)若键值仍为对象,则形成链式援用
(3)对象的属性间用逗号分隔,最初一个属性可加可不加,最好还是加上
对象和变量援用上的区别
变量名援用对象时,是将多个名字指向了同一个地址。批改一个变量,会影响所有变量
var o1 = {};var o2 = o1;o1.a = 1;o2.a // 1o2.b = 2;o1.b // 2
然而多个变量指向一个原始类型的值时,实际上是值的拷贝。批改一个变量,另一个变量不变动
var x = 1;var y = x;x = 2;y // 1
js引擎如何了解对象的大括号
- 对象采纳大括号示意,当js读到大括号时,怎么了解代码呢?
{ foo: 123 }
原本,大括号可能有两种含意。可能是表达式,示意一个蕴含foo属性的对象;也可能是代码区块,里边有标签指向表达式123
为了防止这种歧义,js引擎在遇到这种状况时,一律解释为代码块。因为这种代码,只有解释为代码块能力执行
{ console.log(123) } // 123
- 所以,若果咱们想要引擎把大括号解释为对象,最好在大括号前加上圆括号。因为圆括号的外面,只能是表达式,所以确保大括号只能解释为对象。
这种差别在eval
语句(作用是对字符串求值)中反映得最显著。
eval('{foo: 123}') // 123eval('({foo: 123})') // {foo: 123}
没有圆括号,了解为代码块;有圆括号,了解为对象
属性的操作
读取:能够应用点运算符或者方括号运算符
- 值得注意的是,若应用方括号运算符,键名必须放到引号里边,否则会被当成变量解决
var foo = 'bar';var obj = { foo: 1, bar: 2};obj.['foo']//1obj.foo // 1obj[foo] // 2
- 方括号外部能够应用表达式
obj['hello' + ' world']obj[3 + 3]
- 当键名是数字时,能够不加引号,因为会主动转化为字符串。然而数值键名不能应用点运算符(会被当成小数点),只能应用方括号运算符
var obj = { 123: 'hello world'};obj.123 // 报错obj[123] // "hello world"
其余属性办法
- 赋值:js容许属性的后绑定,即能够在任何时刻新增属性,而没必要在定义对象的时候,就定义好属性。
- 查看:能够应用
Object.keys
办法,查看一个对象的所有属性
var obj = { key1: 1, key2: 2};Object.keys(obj);// ['key1', 'key2']
- 删除:
delete
命令用于删除对象的属性,删除胜利后返回true
。值得注意的是,当删除一个不存在的属性时,delect不会报错,而且返回true;只有当该属性存在且不得删除时,才会返回false;另外,delete命令只能删除对象自身的属性,无奈删除继承的属性
var obj = Object.defineProperty({}, 'p', { value: 123, configurable: false});obj.p // 123delete obj.p // false
var obj = {};delete obj.toString // trueobj.toString // function toString() { [native code] }
下面代码中,toString
是对象obj
继承的属性,尽管delete
命令返回true
,但该属性并没有被删除,仍然存在。这个例子还阐明,即便delete
返回true
,该属性仍然可能读取到值。
- 属性是否存在:
in
运算符用于查看对象是否蕴含某个属性(留神,查看的是键名,不是键值),如果蕴含就返回true
,否则返回false
。它的右边是一个字符串,示意属性名,左边是一个对象。
var obj = { p: 1 };'p' in obj // true'toString' in obj // true
值得注意的是,in不能辨认哪些属性是对象本身的,哪些属性是继承的。咱们能够应用对象的hasOwnProperty
办法判断一下,是否为对象本身的属性。
var obj = {};if ('toString' in obj) { console.log(obj.hasOwnProperty('toString')) // false}
- 遍历:
for...in
循环用来遍历一个对象的全副属性。
var obj = {a: 1, b: 2, c: 3};for (var i in obj) { console.log('键名:', i); console.log('键值:', obj[i]);}
值得注意的是,for...in不仅遍历对象本身的属性,还会遍历继承的属性;然而另一方面,for...in遍历的是对象所有的可遍历属性,会跳过不可遍历的属性。这就解释了为何对象都继承了toString
属性,然而for...in
循环不会遍历到这个属性。
因为toString尽管是继承来的,然而属于不可遍历的,所以不被遍历。