Js学习--对象

1,012 阅读4分钟

引用类型

对象

定义

对象是一组键值对的集合,是一种无序的复合数据集合。

//简写方式
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语句。有兴趣可以自行查看。