当前位置:嗨网首页>书籍在线阅读

19-对象

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

3.12 对象

对象跟不可变的基本类型不太一样,基本类型只能代表一个值,而对象可以代表多个值或者复杂的值,而且这个值在其生命周期内都是可变的。本质上,对象是一个容器,容器的内容可以随着时间推移而改变(也就是同一个对象拥有不同的内容)。跟基本类型一样,对象也有自己语法:大括号({ })。因为大括号是成对出现的,所以可以在大括号内填充对象的内容。下面从一个空对象开始:

const obj = {};
可以给对象任意命名,通常建议取一个表意的名字,比如,user或 `shoppingCart` 。这里只是为了学习对象的原理,例子中的对象没有任何特殊的意义,所以就简单称之为 `obj` 。

对象的内容称作属性(或成员),属性是由名称(或键)和值组成。属性名必须是字符串或者符号,值可以是任意类型(包括其他对象)。接下来给 obj 添加一个 color 属性:

obj.size;             // undefined
obj.color;            // "yellow"

为了使用成员访问运算符,属性名必须是一个合法的标识符。如果想使用非法的标识符作为属性名,必须使用计算机成员访问符(它对合法的标识符也起作用):

obj["not an identifier"] = 3;
obj["not an identifier"];         // 3
obj["color"];                     // "yellow"

也可以使用计算机成员访问操作符来访问符号属性:

const SIZE = Symbol();
obj[SIZE] = 8;
obj[SIZE];                        // 8

上面例子中,obj有三个属性,它们的键(key)分别是 "color" (合法的字符串标识符), "not an identifier" (不合法的字符串标识符), SIZE (符号)。

如果读者在使用JavaScript控制台,可能会注意到控制台不会将 `SIZE` 符号当作 `obj` 的属性列出来。的确(可以输入 `obj[SIZE]` 来验证),符号属性的处理方式会有些不同,一般默认是不显示的。其次要注意,符号属性的键是符号 `SIZE` ,而不是字符串 `"SIZE"` 。为了证明这一点,可以输入 `obj.SIZE = 0` (成员访问操作符始终作用于字符串属性),然后输入 `obj[SIZE]` 和 `obj.SIZE` (或者 `obj["SIZE"]` )。

现在,回忆一下基本类型和对象的区别。本节中,一直在操作和修改变量obj所包含的对象,但是 obj 始终指向同一个对象。假如 obj 被字符串或数字或者任意其他基本类型取代,每一次改变的时候它将变成一个不同的值。换言之, obj 自始至终指向同一个对象,只是对象自身的内容被修改了。

obj 的例子中,创建了一个空对象,对象的语法还允许创建包含初始属性的对象。在大括号内部,属性用逗号间隔,属性名和属性值用冒号隔开。

const sam1 = {
    name: 'Sam',
    age: 4, 
}; 
const sam2 = { name: 'Sam', age: 4 };         // 在同一行声明
const sam3 = {
    name: 'Sam',
    classification: {                         //属性值也可以是对象
        kingdom: 'Anamalia',
        phylum: 'Chordata',
        class: 'Mamalia',
        order: 'Carnivoria',
        family: 'Felidae',
        subfaimily: 'Felinae',
        genus: 'Felis',
        species: 'catus',
    },
}; 

这个例子中,又创建了三个对象来展示对象字面量语法。注意, sam1sam2 包含的属性是一样的,然而,它们却是两个不同的对象(再一次拿基本类型做比较:两个包含数字3的基本类型变量有相同的引用)。对象 sam3classification 属性本身就是一个对象。考虑一下访问 sam3 中classification的属性family的不同方式(无所谓使用单引号、双引号还是重音符):

sam3.classification.family;                  // "Felinae"
sam3["classification"].family;               // "Felinae"
sam3.classification["family"];               // "Felinae"
sam3["classification"]["family"];            // "Felinae"

对象还可以包含函数。第6章会深入学习函数。但现在,只需要知道函数内部包含了代码(实质上是子程序)。来看看如何给 sam3 添加一个函数:

sam3.speak = function() { return "Meow!"; };

现在可以使用方法名+括号的方式调用它:

sam3.speak();             // "Meow!"

最后,可以通过delete操作来删除对象中的属性:

delete sam3.classification;          // 整个classification树被移除
delete sam3.speak;                   // speak函数被移除

如果熟悉面向对象编程(OOP),可能想知道JavaScript对象是如何跟OOP关联起来的。现在,可以先将对象看成是一般的容器,后面会在第9章再详细讨论OOP。