对象是一种可以管理多个属性的 JavaScript 数据类型。属性由键值对组成,您可以通过指定键来检索值。对象通常也称为关联数组。在本文中,我将解释如何在 JavaScript 中使用对象。
目录
12-1 什么是对象
12-2 创建一个对象
12-3 获取属性值并分配新值
12-4 向对象添加和删除属性
12-5 判断对象是否具有指定属性(hasOwnProperty)
12-6 按顺序从对象中提取属性名称(for…in 语句)
12-7 从对象中获取属性名和值的数组(键、值、条目)(key, values, entries)
12-8 从属性名称和值数据创建对象(fromEntries)
12-9 防止给对象添加属性或改变它们的值(freeze)
12-10 将多个对象合并为一个(赋值)(assign)
在我们深入探讨如何使用对象之前,让我们快速了解一下 JavaScript 中的对象是什么以及如何实际使用它。
对象的基本用法
对象以成组合:属性名称(键)和值来管理数据。
由一组属性名称和值表示的数据称为属性。一个对象可以集中管理多个属性。
我们会在另一个页面上解释如何创建一个详细的对象,但是前面的对象可以描述如下。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
在数组中,您可以通过指定索引来检索存储在元素中的值,但在对象中,您可以通过指定属性名称来检索存储在属性中的值。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
console.log(user.name);
>> Yuhua
console.log(user.age);
>> 28
console.log(user.address);
>> Qingdaoshi
属性值可以是数组或函数等对象类型的值,也可以是数字、字符串等原始类型的值。将函数描述为值的属性也称为方法。
您可以使用方法名称调用在对象上注册为值的函数。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi',
hobby:[['读书','旅游','足球']],
getAge:function(){
return this.age;
}
}
console.log(user.getAge());
>> 28
这样一个对象就可以管理多个对象和方法,你可以指定一个属性名(key)来获取一个值或者执行一个函数。我们将在下一页详细介绍如何使用这些对象。
描述如何创建新对象。在 JavaScript 中,有两种创建对象的方法:使用对象字面量和使用 Object 构造函数。
如何编写对象的字面
使用对象字面量创建对象时,请使用以下语法:
{属性名1:值1, 属性名2:值2, 属性名3:值3, ...}
对象中包含的每条数据称为一个属性,每个属性都使用以冒号(:)分隔的属性名(键)和值对来描述,如“属性名:值”。如果包含多个属性,请用逗号(,)分隔并用{}括起来。例如:
let mybox = {'width':400, 'height':300};
let user = {
'name':'Yuhua',
'address':'Qingdaoshi'
}
如果包含多个属性,可以连续写,也可以每个属性另起一行写,这样更容易阅读。
如果要创建一个空对象,可以这样写:稍后可以将属性添加到已创建的对象中。
let colors = {};
对象属性值可以是任何数据类型。您还可以为每个属性指定不同数据类型的值。
let mybox = {
'width':400,
'height':300,
'color':"#FF0000",
'border':[0, 10, 0, 10]
};
属性名怎么写
属性名称使用字符串或 Symbol 对象编写。(我将单独解释如何使用Sysmbol)。属性名中可以写任何字符串,但如果字符串有一个值遵循与变量名等相同的规则,则省略表示字符串的单引号,使用如下: 即可写在
{width:400, height:300};
如果属性名不符合变量名规则,例如属性名首字符为数字或中间有空格,则像普通字符串一样用单引号或双引号括起来.
myprofile = {
'1stName':'Yuhua', // 属性名第一个字符为数字
'Favorite color':'Blue' // 属性名包含空格
};
如果省略单引号,即使属性名称以数字开头,也会发生错误。
let myprofile = {
1stName:'Yuhua',
};
>> Uncaught SyntaxError: Invalid or unexpected token
将表达式指定为属性值
在编写对象字面量时,可以在对象的值中写入变量和表达式。看看下面的示例。
let base = 1000;
let mybox = {
width:base,
height:base * 0.5
};
console.log(mybox);
>> {width: 1000, height: 500}
变量或表达式被指定为属性的值。如果指定了变量,则存储存储在变量中的值,如果指定表达式,则将通过计算表达式获得的值存储为属性值。
从 Object 对象创建对象
Object 对象是 JavaScript 提供的内置对象之一。要创建一个对象,您可以使用前面解释的对象字面量来创建它,但您也可以使用 Object 对象的构造函数来创建它。格式如下。
new Object()
创建一个没有属性的空对象。这与在对象字面量中写入 {} 相同。
let obj = new Object();
console.log(obj);
>> {}
创建空对象后,您将开始向其添加属性。
要获取已创建对象中包含的属性的值或为其分配新值,请通过指定属性名称来访问该属性以获取或分配该值。这里我们解释如何获取属性的值以及如何分配新值。
使用句点运算符形式访问
访问对象属性的一种方法是采用句点运算符的形式。格式如下。
オブジェクト.プロパティ名
在对象后面写一个句点(.),然后写上你要访问的属性的属性名。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
console.log(user.name);
>> Yuhua
这次,通过将名称指定为属性名称来引用属性值。山田太郎因此被退回。
您还可以通过分配新值来更改属性的值。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
user.name = 'Jiangming';
console.log(user);
>> {name: "Jiangming", age: 28, address: "Qingdaoshi"}
请注意,仅当属性名称的值遵循与变量名称等相同的规则时,才能以句点运算符的形式访问属性。例如,如果属性名称以数字开头或包含连字符,则不能使用句点运算符形式。
如果您尝试使用句点运算符格式访问其值以数字开头的属性,如以下示例所示,则会发生错误。
myprofile = {
'1stName':'Yamada',
'Favorite color':'Blue'
};
console.log(myprofile.1stName);
>> Uncaught SyntaxError: missing ) after argument list
如果属性名值不遵循与变量名等相同的规则,则使用下面描述的方括号 [] 格式访问属性。
以方括号[]形式访问
访问对象属性的另一种方法是通过方括号 [] 形式。格式如下。
对象['属性名称']
在对象后面写上方括号[],在[]里面写上你要访问的属性的属性名作为字符串。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
console.log(user['name']);
>> Yuhua
这次,通过将名称指定为属性名称来引用属性值。山田太郎因此被退回。
您还可以通过分配新值来更改属性的值。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
}
user['name'] = 'Jiangming';
console.log(user);
>> {name: "Jiangming", age: 28, address: "Qingdaoshi"}
使用方括号 [] 格式时,属性名称可以是任何字符串。因此,您可以访问值以数字开头的属性,如下例所示。
myprofile = {
'1stName':'Yuhua',
'Favorite color':'Blue'
};
console.log(myprofile['1stName']);
>> Yuhua
将变量指定为属性名称的值
使用方括号 [] 格式时,可以将变量指定为属性名称。请看下面的示例。
let colorDB = {
red:'红色',
blue:'蓝色',
yellow:'黄色'
}
let color = 'blue';
console.log(colorDB[color]);
>> 蓝色
如果将变量指定为属性名称值,则访问该属性就好像存储在变量中的值被指定为属性名称一样。请注意,只有在使用方括号 [] 格式时,才能将变量指定为属性名称。不能以句点运算符形式使用。
JavaScript 允许您添加新属性并从您创建的对象中删除现有属性。本节介绍如何向对象添加新属性以及如何删除现有属性。
添加属性
要向对象添加新属性,请为对象中不存在的属性名称分配一个值。看看下面的示例。
let mybox = {
width:400,
height:300
};
console.log(mybox);
>> {width: 400, height: 300}
mybox.color = '#FF0000'; // 添加新属性
console.log(mybox);
>> {width: 400, height: 300, color: "#FF0000"}
您正在为当前不存在的属性名称为 color 的对象分配一个值。对象中添加了一个新属性,该属性由属性名称/值对组成。
您可以使用句点运算符或方括号 [] 指定属性名称并分配值。
删除属性
如果要从对象中删除属性,请使用删除运算符。格式如下。
delete object.property 名称
delete ['属性名称']
在删除操作符的右边写上要删除的属性。可以使用句点运算符或方括号 [] 指定属性。
看看下面的示例。
let mybox = {
width:400,
height:300,
color:'#FF0000'
};
console.log(mybox);
>> {width: 400, height: 300, color: "#FF0000"}
delete mybox.height; // 删除属性
console.log(mybox);
>> {width: 400, color: "#FF0000"}
指定的属性已从对象中删除。
尝试删除不存在的属性不会导致错误。看看下面的示例。
let mybox = {
width:400,
height:300,
color:'#FF0000'
};
delete mybox.border; // 删除不存在的属性
console.log(mybox);
>> {width: 400, height: 300, color: "#FF0000"}
尝试删除对象中不存在的属性名称为 border 的属性不会导致错误,并且对象保持原样。
您可以使用 Object 对象的 hasOwnProperty 方法检查对象是否具有指定的属性。本节介绍如何确定对象是否具有指定属性。
检查对象是否有属性
使用 Object 对象的 hasOwnProperty 方法来确定对象是否具有指定的属性。格式如下。
object.hasOwnProperty(属性名)
指定一个字符串或 Symbol 对象,表示参数中属性的属性名称。如果存在匹配的属性,则返回 true,否则返回 false。
看看下面的示例。
let mybox = {
width:400,
height:300
};
console.log(mybox.hasOwnProperty('width'));
>> true
console.log(mybox.hasOwnProperty('color'));
>> false
对具有现有属性名称 width 的对象调用 hasOwnProperty 方法返回 true,对不存在的属性名称 color 返回 false。
迭代 for…in 语句可用于按顺序检索对象中包含的属性的属性名称。本节介绍如何按顺序从对象中提取属性名称。
for…in 语句可用于迭代对象中包含的属性的属性名称。格式如下。
for (变量名 in 对象){
...
}
在变量中按顺序存储对象的属性名称后,执行块中的处理。请注意,它是存储在变量名称中的属性名称。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
for (key in user){
console.log('user.'+ key + '=' + user[key]);
}
>> user.name=Yuhua
>> user.age=28
>> user.address=Qingdaoshi
在变量中按顺序存储属性名称后,在迭代过程中获取属性值并输出到控制台。请注意,属性名称作为字符串存储在变量中,因此在检索属性值时,请使用格式对象[属性名称] 而不是格式对象.属性名称。
通过使用Object对象的keys方法、values方法和entries方法,可以得到对象中包含的属性名和属性值的列表,作为一个数组。在这里,我们将解释如何在 JavaScript 中从数组中的对象中获取属性名称和值的列表。
获取属性名称列表(键)(keys)
使用 Object 对象的 keys 方法获取对象中包含的属性的属性名称列表。格式如下。
Object.keys(对象)
以数组形式获取指定为参数的对象中包含的属性名称列表。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
let keyArray = Object.keys(user);
console.log(keyArray);
>> ["name", "age", "address"]
我能够获得一个数组,其中包含对象中包含的三个属性的属性名称作为元素。每个属性名称都作为字符串存储在数组中。
通过使用Array对象的forEach方法依次获取数组的元素,也可以依次获取属性值。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
let keyArray = Object.keys(user);
keyArray.forEach(function(element){
console.log(user[element]);
});
>> Yuhua
>> 28
>> Qingdaoshi
在一个数组中取出对象包含的属性名列表后,依次从数组中取出元素,依次取出对象的属性值,显示在控制台上。
获取属性值列表(values)
使用Object对象的values方法获取对象包含的属性的值列表。格式如下。
Object.values(对象)
以数组的形式获取参数中指定的对象中包含的属性值列表。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
let valueArray = Object.values(user);
console.log(valueArray);
>> ["Yuhua", 28, "Qingdaoshi"]
我能够得到一个数组,该数组以对象中包含的三个属性的值作为元素。
获取属性名称和值的列表(entries)
使用 Object 对象的 entries 方法获取对象中包含的属性名/值对列表。格式如下。
Object.entries(对象)
为参数中指定的对象中包含的每个属性获取 [property name, value] 的列表作为数组。
看看下面的示例。
let user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
let propertyArray = Object.entries(user);
propertyArray.forEach(function(element){
console.log(element);
});
>> ["name", "Yuhua"]
>> ["age", 28]
>> ["address", "Qingdaoshi"]
对于对象中包含的三个属性,我们能够获得一个以属性名称和值作为元素的数组。
我们可以使用 fromEntries 方法(Object 对象的一种方法)从二值数据列表创建对象。例如,您可以从一个数组创建一个对象,该数组的元素是具有两个元素的数组。本节介绍如何在 JavaScript 中根据属性名称和值数据创建对象。
从属性名称和值数据创建对象 (fromEntries)
使用 Object 对象的 fromEntries 方法从属性和值数据创建对象。格式如下。
Object.fromEntries(对象)
参数是一个可迭代对象。特别是 Array 对象或 Map 对象。执行该方法从指定为参数的对象创建一个新的 Object 对象。
指定为参数的对象指定两个值配对的数据。第一个值存储为属性名称,第二个值存储为属性值。
看看下面的示例。
let userArray = [
['name', 'Yuhua'],
['age', 28],
['address', 'Qingdaoshi']
];
let userObj = Object.fromEntries(userArray);
console.log(userObj);
>> {name: "Yuhua", age: 28, address: "Qingdaoshi"}
我能够从一个数组创建一个新对象,该数组的元素是一个包含两个元素的数组。
请注意,如果指定为参数的对象的数据仅包含一个值而不是一对两个值,则创建的对象的相应属性的值将为 undefined 。看看下面的示例。
let userArray = [
['name', 'Yuhua'],
['age'], // 只有一个值
['address', 'Qingdaoshi']
];
let userObj = Object.fromEntries(userArray);
console.log(userObj);
>> {name: "Yuhua", age: undefined, address: "Qingdaoshi"}
创建的对象中属性名为age的属性值未定义。
您可以使用 Object 对象的 freeze 方法来阻止向对象添加或删除属性。您也将无法更改现有属性的值。本节介绍如何防止在 JavaScript 中向对象添加属性或更改属性值。
禁止属性更改(冻结)(freeze)
要防止更改对象,请使用 Object 对象的冻结方法。格式如下。
Object.freeze(对象)
执行该方法后,您将无法添加新属性或从参数中指定的对象中删除现有属性。您也将无法更改现有属性的值。
看看下面的示例。
const user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
user.address = 'Shanghaishi';
console.log(user);
>> {name: "Yuhua", age: 28, address: "Shanghaishi"}
使用 const 将对象分配给变量只会阻止您将新对象分配给同一变量,可变对象以后可以更改其属性的值。
要使创建的对象的属性不可修改,并禁止添加属性和修改属性值,请通过将目标对象指定为参数来调用 freeze 方法,如下例所示。
const user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
Object.freeze(user);
user.address = 'Shanghaishi'; // 改变属性值
console.log(user);
>> {name: "Yuhua", age: 28, address: "Qingdaoshi"}
更改对象属性的值不会导致错误,但原始值保持不变。
现在调用 freeze 方法后,尝试添加新属性并删除现有属性。
const user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
Object.freeze(user);
user.hobby = 'Movie'; // 添加新属性
delete user.age; // 删除现有属性
console.log(user);
>> {name: "Yuhua", age: 28, address: "Qingdaoshi"}
添加新属性或删除现有属性不会导致错误,但不会实际添加属性或删除现有属性。
通过使用冻结方法以这种方式使对象不可变,就不可能改变属性值或添加新的属性。
请注意,如果启用了严格模式,如果您尝试更改属性的值或在使其不可修改后添加新属性,则会发生错误。
'use strict';
const user = {
name:'Yuhua',
age:28,
address:'Qingdaoshi'
};
Object.freeze(user);
user.address = 'Shanghai'; // 改变属性
>> Uncaught TypeError: Cannot assign to read only property 'address' of object '#<Object>'
使数组不可变
可以使用数组作为参数调用 Object.freeze 方法,而不仅仅是对象。那么您将无法更改数组元素的值或添加新元素。
看看下面的示例。
const point = [48, 72, 65];
Object.freeze(point);
point[1] = 78; // 改变元素
point[3] = 54; // 添加元素
console.log(point);
>> [48, 72, 65]
更改数组元素的值或添加新元素不会导致错误,但实际上不会更改元素的值或添加新元素。
如果属性值是一个对象
通过调用 freeze 方法只能禁用方法参数中指定的对象的属性。如果另一个对象或数组存储为属性的值,则可以更改子对象的属性。
看看下面的示例。
let user = {
name:'Yuhua',
hobby:['Movie', 'Game']
};
Object.freeze(user);
user.name = 'Jiangming'; // 改变属性值
user.hobby[0] = 'Sports'; // 改变子对象(数组)元素的值
console.log(user.hobby);
>> ["Sports", "Game"]
即使你使对象不可变,你仍然可以改变子对象的属性值。
要使子对象(包括子对象)不可变,还必须在子对象上调用 freeze 方法。
let user = {
name:'Yuhua',
hobby:['Movie', 'Game']
};
Object.freeze(user.hobby);
Object.freeze(user);
user.hobby[0] = 'Sports'; // 改变子对象(数组)元素的值
console.log(user.hobby);
>> ["Movie", "Game"]
我也能够使子对象的属性值不可变。
在前面的示例中,目标子对象被显式指定为不可修改,需要描述处理,如顺序检查值,如果是对象则不可修改。另外,如果有可能不仅包含子对象,还包含孙对象,则需要递归地检查是否包含对象。
通过使用 Object 对象的方法 assign 方法,您可以获得将多个对象组合为一个的对象。您还可以使用相同的方法创建对象的克隆。在这里,我将解释如何在 JavaScript 中将多个对象合并为一个对象。
将多个对象合并为一个(赋值)(assign)
要将多个对象合并为一个,请使用 Object 对象的 assign 方法。格式如下。
Object.assign(目标对象,源对象 1,源对象 2,...)
第一个参数是要复制到的对象。将第二个及后续对象的属性按顺序复制并添加到此对象中。返回值是附加后的目标对象。
请注意,目标对象本身将被修改,因为在其他参数中指定的对象的属性被添加到目标对象。
看看下面的示例。
let objA = {a:'Ant'};
let objB = {b:'bee'};
let objC = {c:'cicada'};
let allObj = Object.assign(objA, objB, objC);
console.log(allObj);
>> {a: "Ant", b: "bee", c: "cicada"}
console.log(objA);
>> {a: "Ant", b: "bee", c: "cicada"}
三个对象中包含的属性已合并为一个。请注意,其他对象的属性被添加到 assign 方法的第一个参数对象中,而不是创建一个具有所有属性的新对象。assign 方法的返回值与第一个参数对象相同。
如果你想在不改变现有对象的情况下获得一个结合了对象属性的对象,指定一个空对象{}作为assign方法的第一个参数。看看下面的示例。
let objA = {a:'Ant'};
let objB = {b:'bee'};
let objC = {c:'cicada'};
let allObj = Object.assign({}, objA, objB, objC);
console.log(allObj);
>> {a: "Ant", b: "bee", c: "cicada"}
其他对象的属性按顺序添加到空对象中,你可以得到合并后的对象作为返回值。
如果对象中存在具有相同属性名的属性,它将被后面描述的属性覆盖。看看下面的示例。
let objA = {a:'Ant', b:'bee'};
let objB = {c:'cicada', b:'butterfly'};
let allObj = Object.assign({}, objA, objB);
console.log(allObj);
>> {a: "Ant", b: "butterfly", c: "cicada"}
要组合的两个对象各包含一个属性名称为 b 的属性。在这种情况下,它将被后面编写的属性覆盖。
创建对象的副本
您可以通过仅指定一个对象并为空对象调用 assign 方法来创建对象的副本。看看下面的示例。
let obj = {a:'Ant', b:'bee'};
let cloneObj = Object.assign({}, obj);
console.log(cloneObj);
>> {a: "Ant", b: "bee"}
console.log(obj === cloneObj);
>> false
创建在 assign 方法的第二个参数中指定的对象的克隆,并将其作为返回值。请注意,属性被添加到第一个参数,一个空对象,因此这两个对象具有相同名称和值的相同属性,但它们是不同的对象。