引用类型
对象
定义
对象是一组键值对的集合,是一种无序的复合数据集合。
//简写方式
var obj={
foo:'hello',
bar:'world'
}
//标准方式
var obj=new Object({
foo:'hello',
bar:'world'
})
通过大括号去定义一个对象,然后赋值给变量obj
。因此,obj
指向一个对象。
键名
对象的所有键名都是字符串,所以加不加引号都可以。 如果键名是数值,会被自动转化为字符串。如果键名不符合标识名的条件(比如第一个字符为数字,或者含有空格或运算符),且也不是数字,则必须加上引号,否则会报错。
// 报错
var obj = {
1p: 'Hello World'
};
// 不报错
var obj = {
'1p': 'Hello World',
'h w': 'Hello World',
'p+q': 'Hello World'
};
动态键名
通过中括号将变量设置为键名,如果中括号内不是表达式,会先进行求值,在转化为字符串。
var a='xxx'
var obj={
[a]:'hello'
}
对象的每一个键名又称为“属性”(property),它的“键值”可以是任何数据类型。如果属性的值还是一个对象,就形成了链式引用。
var o1 = {};
var o2 = { bar: 'hello' };
o1.foo = o2;
o1.foo.bar // "hello"
//链式调用 :o1.foo.o2
属性可以动态创建,不必在对象声明时就指定。
对象的引用
如果不同的变量名指向同一个对象,那么它们都是这个对象的引用,也就是说指向同一个内存地址。修改其中一个变量,会影响到其他所有变量。但是,这种引用只局限于对象,如果两个变量指向同一个原始类型的值。那么,变量这时都是值的拷贝。
表达式和代码块
对象采用大括号表示,这导致了一个问题:如果行首是一个大括号,它到底是表达式还是代码块?为了避免这种歧义,JavaScript 引擎的做法是,如果遇到这种情况,无法确定是对象还是代码块,一律解释为代码块。 如果希望将{}解释为代码块,就无需处理,如果需要解释为表达式,就加上({}),因为圆括号的里面,只能是表达式,所以确保大括号只能解释为对象。
属性的操作
读取
读取对象的属性使用两种方法:
- 点运算符
- 方括号运算符
var foo = 'bar';
var obj = {
foo: 1,
bar: 2
};
obj.foo // 1 点运算符引用的foo是字符串
obj[foo] // 2 方括号运算符引用的foo是变量
数值键名不能使用点运算符(因为会被当成小数点),只能使用方括号运算符。
赋值
点运算符和方括号运算符,不仅可以用来读取值,还可以用来赋值。JavaScript 允许属性的“后绑定”,也就是说,你可以在任意时刻新增属性,没必要在定义对象的时候,就定义好属性。
批量赋值:Object.assign(obj, {age: 18, gender: 'man'})
更改原型:通过Object.create
方法将原型指向定义的对象,而非默认对象。let obj = Object.create(common)
查看
查看一个对象本身的所有属性,可以使用Object.keys
方法。查看一个对象的单个属性,可以使用obj.key或obj['key']
方法。
删除
delete
命令用于删除对象的属性,删除成功后返回true
。delete命令只能删除对象本身的属性,无法删除继承的属性。
var obj = { p: 1 };
Object.keys(obj) // ["p"]
delete obj.p // true
delete obj[p]//
obj.p // undefined
Object.keys(obj) // []
删除一个不存在的属性,delete不报错,而且返回true
属性存在检定:in运算符
in
运算符检定对象是否包含某个属性(所有属性中检查)。
hasOwnProperty
方法检定对象是否自身含有某个属性。
var obj = { p: 1 };
'p' in obj // true 自身的
'toString' in obj // true 继承的
var obj = {};
if ('toString' in obj) {
console.log(obj.hasOwnProperty('toString')) // false
}
属性遍历:for...in 循环
for...in
循环用来遍历一个对象的全部属性。
- 它遍历的是对象所有可遍历(enumerable)的属性,会跳过不可遍历的属性。
- 它不仅遍历对象自身的属性,还遍历继承的属性。
如果继承的属性是可遍历的,那么就会被for...in循环遍历到。但是,一般情况下,都是只想遍历对象自身的属性,所以使用for...in的时候,应该结合使用hasOwnProperty方法,在循环内部判断一下,某个属性是否为对象自身的属性。
with语句
建议不要使用with语句。有兴趣可以自行查看。