对象
回到松鼠人的示例。 一组每日的日志条目可以表示为一个数组。 但是这些条目并不仅仅由一个数字或一个字符串组成 - 每个条目需要存储一系列活动和一个布尔值,表明雅克是否变成了松鼠。 理想情况下,我们希望将它们组合成一个值,然后将这些分组的值放入日志条目的数组中。
对象类型的值是任意的属性集合。 创建对象的一种方法是使用大括号作为表达式。
let day1 = {
squirrel: false,
events: ["work", "touched tree", "pizza", "running"]
};
console.log(day1.squirrel);
// → false
console.log(day1.wolf);
// → undefined
day1.wolf = false;
console.log(day1.wolf);
// → false
大括号内有一列用逗号分隔的属性。 每个属性都有一个名字,后跟一个冒号和一个值。 当一个对象写为多行时,像这个例子那样,对它进行缩进有助于提高可读性。 名称不是有效绑定名称或有效数字的属性必须加引号。
let descriptions = {
work: "Went to work",
"touched tree": "Touched a tree"
};
这意味着大括号在 JavaScript 中有两个含义。 在语句的开头,他们起始了一个语句块。 在任何其他位置,他们描述一个对象。 幸运的是,语句很少以花括号对象开始,因此这两者之间的不明确性并不是什么大问题。
读取一个不存在的属性就会产生undefined
。
我们可以使用=运算符来给一个属性表达式赋值。如果该属性已经存在,那么这项操作就会替换原有的值。如果该属性不存在,则会在目标对象中新建一个属性。
简要回顾我们的绑定的触手模型 - 属性绑定也类似。 他们捕获值,但其他绑定和属性可能会持有这些相同的值。 你可以将对象想象成有任意数量触手的章鱼,每个触手上都有一个名字的纹身。
delete
运算符切断章鱼的触手。 这是一个一元运算符,当应用于对象属性时,将从对象中删除指定的属性。 这不是一件常见的事情,但它是可能的。
let anObject = {left: 1, right: 2};
console.log(anObject.left);
// → 1
delete anObject.left;
console.log(anObject.left);
// → undefined
console.log("left" in anObject);
// → false
console.log("right" in anObject);
// → true
当应用于字符串和对象时,二元in
运算符会告诉你该对象是否具有名称为它的属性。 将属性设置为undefined
,和实际删除它的区别在于,在第一种情况下,对象仍然具有属性(它只是没有有意义的值),而在第二种情况下属性不再存在,in
会返回false
。
为了找出对象具有的属性,可以使用Object.keys
函数。 你给它一个对象,它返回一个字符串数组 - 对象的属性名称。
console.log(Object.keys({x: 0, y: 0, z: 2}));
// → ["x", "y", "z"]
Object.assign
函数可以将一个对象的所有属性复制到另一个对象中。
let objectA = {a: 1, b: 2};
Object.assign(objectA, {b: 3, c: 4});
console.log(objectA);
// → {a: 1, b: 3, c: 4}
然后,数组只是一种对象,专门用于存储对象序列。 如果你求解typeof []
,它会产生object
。 你可以看到它们是长而平坦的章鱼,它们的触手整齐排列,并以数字标记。
我们将雅克的日记表示为对象数组。
let journal = [
{events: ["work", "touched tree", "pizza",
"running", "television"],
squirrel: false},
{events: ["work", "ice cream", "cauliflower",
"lasagna", "touched tree", "brushed teeth"],
squirrel: false},
{events: ["weekend", "cycling", "break", "peanuts",
"beer"],
squirrel: true},
/* and so on... */
];