原来 JavaScript Object 对象还能这么用!

简介

JavaScript 中的对象是键/值对的集合。值可以由属性和方法组成,并且可以包含所有其他的 JavaScript 数据类型,例如字符串、数字和布尔值。

JavaScript 中的所有对象都来自父 Object 构造函数。Object 有许多有用的内置属性和方法可供我们使用和访问。与用于数组实例的诸如 sort()和 reverse()等数组原型方法不同,对象方法直接在 Object 构造函数上使用,并将对象实例用作参数。这就是所谓的静态方法。

本教程将介绍一些重要的内置对象方法。

Object.create()

Object.create()方法用于创建新对象并将其链接到现有对象的原型。

让我们创建一个 job 对象实例,并将其扩展到更具体的对象。

// 用属性和方法初始化一个对象
const job = {
    position: "cashier",
    type: "hourly",
    isAvailable: true,
    showDetails() {
        const accepting = this.isAvailable
            ? "is accepting applications"
            : "is not currently accepting applications";

        console.log(
            `The ${this.position} position is ${this.type} and ${accepting}.`
        );
    },
};

// 使用Object.create传递属性
const barista = Object.create(job);

barista.position = "barista";
barista.showDetails();

// 输出
// The barista position is hourly and is accepting applications.

barista 对象现在有了一个属性:position,来自 job 的所有其他属性和方法都可以通过原型获得。Object.create()通过减少重复来保持代码整洁高效。

Object.keys()

Object.keys()创建一个数组,该数组包含对象的所有键。

让我们创建一个对象并打印键的数组。

// 创建并初始化一个对象
const employees = {
    boss: "Michael",
    secretary: "Pam",
    sales: "Jim",
    accountant: "Oscar",
};

// 获取对象中的所有键
const keys = Object.keys(employees);

console.log(keys);

// 输出
// ["boss", "secretary", "sales", "accountant"]

由于 Object.keys 将对象的键转换为键的数组,因此 forEach()数组方法可用于遍历键和值。

// 遍历所有的键
Object.keys(employees).forEach((key) => {
    let value = employees[key];

    console.log(`${key}: ${value}`);
});

// 输出
// boss: Michael
// secretary: Pam
// sales: Jim
// accountant: Oscar

Object.keys 对于使用 length 属性检查转换后的数组的长度也很有用。

// 获取所有键集合的长度
const length = Object.keys(employees).length;

console.log(length);

// 输出
// 4

通过 length 属性,我们能够计算 employees 对象有 4 个属性。

Object.values()

Object.values()创建一个数组,该数组包含对象中所有键的值。

// 创建并初始化一个对象
const session = {
    id: 1,
    time: `26-July-2018`,
    device: "mobile",
    browser: "Chrome",
};

// 获取对象所有键的值
const values = Object.values(session);

console.log(values);

// 输出
// [1, "26-July-2018", "mobile", "Chrome"]

由此我们可以看到,Object.keys()和 Object.values()允许你从对象返回数据。

Object.entries()

Object.entries()创建对象的键/值对的嵌套数组。

// 创建并初始化一个对象
const operatingSystem = {
    name: "Ubuntu",
    version: 18.04,
    license: "Open Source",
};

// 获取对象中的键/值对
const entries = Object.entries(operatingSystem);

console.log(entries);

// 输出
// [
//     ["name", "Ubuntu"]
//     ["version", 18.04]
//     ["license", "Open Source"]
// ]

有了键/值对数组之后,我们就可以使用 forEach()方法循环并处理结果。

// 遍历键/值对数组
entries.forEach((entry) => {
    let key = entry[0];
    let value = entry[1];

    console.log(`${key}: ${value}`);
});

// 输出
// name: Ubuntu
// version: 18.04
// license: Open Source

Object.entries()方法将只返回对象实例自己的属性,而不是任何可能通过原型继承的属性。

Object.assign()

Object.assign()用于将值从一个对象复制到另一个对象。

创建两个对象,并将它们通过 Object.assign()合并。

// 创建并初始化对象
const name = {
    firstName: "Philip",
    lastName: "Fry",
};

// 创建并初始化另一个对象
const details = {
    job: "Delivery Boy",
    employer: "Planet Express",
};

// 合并两个对象
const character = Object.assign(name, details);

console.log(character);

// 输出
// {firstName: "Philip", lastName: "Fry", job: "Delivery Boy", employer: "Planet Express"}

我们也可以使用展开运算符(...)来完成相同的任务。在下面的代码中,我们将通过合并 name 和 details 对象来修改声明 character 的方式。

// 创建并初始化对象
const name = {
    firstName: "Philip",
    lastName: "Fry",
};

// 创建并初始化另一个对象
const details = {
    job: "Delivery Boy",
    employer: "Planet Express",
};

// 使用展开运算符合并两个对象
const character = { ...name, ...details };

console.log(character);

// 输出
// {firstName: "Philip", lastName: "Fry", job: "Delivery Boy", employer: "Planet Express"}

对象字面量中的这种扩展语法也称为浅克隆。

Object.freeze()

顾名思义,Object.freeze()方法就是冻结对象的意思,可以防止修改对象的属性和值,也可以防止从对象中添加或删除属性。

// 创建并初始化对象
const user = {
    username: "AzureDiamond",
    password: "hunter2",
};

// 冻结对象
const newUser = Object.freeze(user);

newUser.password = "*******";
newUser.active = true;

console.log(newUser);

// 输出
// {username: "AzureDiamond", password: "hunter2"}

在上面的示例中,我们试图用*******覆盖密码 hunter2,但 password 属性保持不变。我们还试图添加一个新的属性 active,但添加不了。

Object.isFrozen()可用于确定对象是否已被冻结,并返回布尔值。

Object.seal()

Object.seal()防止将新属性添加到对象,但允许修改现有属性。有点类似于 Object.freeze()。在执行以下代码之前刷新控制台以避免错误。

// 创建并初始化对象
const user = {
    username: "AzureDiamond",
    password: "hunter2",
};

// Seal the object
const newUser = Object.seal(user);

newUser.password = "*******";
newUser.active = true;

console.log(newUser);

// 输出
// {username: "AzureDiamond", password: "*******"}

新的active属性未添加到密封对象,但password属性已成功更改。

Object.getPrototypeOf()

Object.getPrototypeOf()用于获取对象内部隐藏的[[Prototype]],也可以通过__proto__属性访问。

让我们创建一个可以访问Array原型的数组。

const employees = ['Ron', 'April', 'Andy', 'Leslie'];

Object.getPrototypeOf(employees);

// 输出
// [constructor: ƒ, concat: ƒ, find: ƒ, findIndex: ƒ, pop: ƒ, …]

在输出中可以看到,employees数组的原型可访问pop、find和其他数组原型方法。我们可以通过测试employees原型的Array.prototype来确认这一点。

Object.getPrototypeOf(employees) === Array.prototype;

// 输出
// true

此方法可用于获取有关对象的更多信息或确保可以访问另一个对象的原型。

还有一个相关的Object.setPrototypeOf()方法,是将原型添加到另一个对象。

贡献者: mankueng