JavaScript对象

对象是JavaScript中的核心概念,是一种复合数据类型,可以存储多个键值对。几乎所有的JavaScript值都是对象,除了基本数据类型(字符串、数字、布尔值、null、undefined、符号、大整数)。

对象的创建

JavaScript提供了多种创建对象的方式。

对象字面量

使用花括号{}创建对象:

javascript
const person = {
    name: "John",
    age: 30,
    isActive: true
};

Object构造函数

使用Object构造函数创建对象:

javascript
const person = new Object();
person.name = "John";
person.age = 30;
person.isActive = true;

构造函数

使用自定义构造函数创建对象:

javascript
function Person(name, age) {
    this.name = name;
    this.age = age;
    this.isActive = true;
}

const person = new Person("John", 30);

Object.create()

使用Object.create()方法创建对象:

javascript
const personPrototype = {
    greet: function() {
        return "Hello, " + this.name + "!";
    }
};

const person = Object.create(personPrototype);
person.name = "John";
person.age = 30;

ES6引入的类语法:

javascript
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
        this.isActive = true;
    }
    
    greet() {
        return "Hello, " + this.name + "!";
    }
}

const person = new Person("John", 30);

对象的属性

属性是对象的键值对。

属性访问

可以使用点号.或方括号[]访问对象属性:

javascript
const person = { name: "John", age: 30 };

console.log(person.name); // John
console.log(person["age"]); // 30

方括号语法的优点:

  • 可以使用变量作为属性名
  • 可以使用包含特殊字符的属性名
javascript
const person = { "first name": "John", age: 30 };
const propName = "age";

console.log(person[propName]); // 30
console.log(person["first name"]); // John

属性赋值

javascript
const person = {};

// 点号语法
person.name = "John";

// 方括号语法
person["age"] = 30;

属性删除

使用delete操作符删除对象的属性:

javascript
const person = { name: "John", age: 30 };
delete person.age;
console.log(person.age); // undefined

属性存在性检查

使用in操作符或hasOwnProperty()方法检查属性是否存在:

javascript
const person = { name: "John", age: 30 };

console.log("name" in person); // true
console.log(person.hasOwnProperty("age")); // true
console.log("gender" in person); // false

属性遍历

使用for...in循环遍历对象的可枚举属性:

javascript
const person = { name: "John", age: 30, isActive: true };

for (let prop in person) {
    console.log(prop + ": " + person[prop]);
}

使用Object.keys()获取对象的可枚举自有属性名:

javascript
const person = { name: "John", age: 30, isActive: true };
const keys = Object.keys(person);
console.log(keys); // ["name", "age", "isActive"]

使用Object.values()获取对象的可枚举自有属性值:

javascript
const person = { name: "John", age: 30, isActive: true };
const values = Object.values(person);
console.log(values); // ["John", 30, true]

使用Object.entries()获取对象的可枚举自有属性键值对:

javascript
const person = { name: "John", age: 30, isActive: true };
const entries = Object.entries(person);
console.log(entries); // [["name", "John"], ["age", 30], ["isActive", true]]

对象的方法

方法是对象的属性,其值是函数。

方法定义

javascript
const person = {
    name: "John",
    age: 30,
    greet: function() {
        return "Hello, " + this.name + "!";
    }
};

// ES6简写语法
const person = {
    name: "John",
    age: 30,
    greet() {
        return "Hello, " + this.name + "!";
    }
};

方法调用

javascript
const person = {
    name: "John",
    greet() {
        return "Hello, " + this.name + "!";
    }
};

console.log(person.greet()); // Hello, John!

this关键字

在对象方法中,this指向调用该方法的对象:

javascript
const person1 = {
    name: "John",
    greet() {
        return "Hello, " + this.name + "!";
    }
};

const person2 = {
    name: "Jane",
    greet() {
        return "Hello, " + this.name + "!";
    }
};

console.log(person1.greet()); // Hello, John!
console.log(person2.greet()); // Hello, Jane!

对象的原型

每个JavaScript对象都有一个原型对象,对象可以从原型继承属性和方法。

__proto__属性

使用__proto__属性访问对象的原型:

javascript
const person = { name: "John" };
console.log(person.__proto__); // Object.prototype

Object.getPrototypeOf()

使用Object.getPrototypeOf()方法获取对象的原型:

javascript
const person = { name: "John" };
const proto = Object.getPrototypeOf(person);
console.log(proto); // Object.prototype

Object.setPrototypeOf()

使用Object.setPrototypeOf()方法设置对象的原型:

javascript
const personPrototype = { greet: function() { return "Hello!"; } };
const person = { name: "John" };

Object.setPrototypeOf(person, personPrototype);
console.log(person.greet()); // Hello!

对象的属性描述符

对象的每个属性都有一个属性描述符,用于描述属性的特性。

获取属性描述符

使用Object.getOwnPropertyDescriptor()方法获取属性描述符:

javascript
const person = { name: "John" };
const descriptor = Object.getOwnPropertyDescriptor(person, "name");
console.log(descriptor);
// {
//   value: "John",
//   writable: true,
//   enumerable: true,
//   configurable: true
// }

属性描述符的特性

  • value:属性的值
  • writable:是否可以修改属性的值
  • enumerable:是否可以枚举(for…in循环和Object.keys()是否包含该属性)
  • configurable:是否可以删除属性或修改属性描述符

设置属性描述符

使用Object.defineProperty()方法设置属性描述符:

javascript
const person = {};

Object.defineProperty(person, "name", {
    value: "John",
    writable: false, // 不可修改
    enumerable: true,
    configurable: true
});

person.name = "Jane"; // 不会生效
console.log(person.name); // John

对象的方法

JavaScript提供了许多内置的对象方法。

Object.assign()

将一个或多个源对象的属性复制到目标对象:

javascript
const target = { a: 1 };
const source1 = { b: 2 };
const source2 = { c: 3 };

const result = Object.assign(target, source1, source2);
console.log(result); // { a: 1, b: 2, c: 3 }

Object.freeze()

冻结对象,使其属性不能被修改、添加或删除:

javascript
const person = { name: "John", age: 30 };
Object.freeze(person);

person.name = "Jane"; // 不会生效
delete person.age; // 不会生效
person.gender = "male"; // 不会生效

console.log(person); // { name: "John", age: 30 }

Object.seal()

密封对象,使其属性不能被添加或删除,但可以修改现有属性:

javascript
const person = { name: "John", age: 30 };
Object.seal(person);

person.name = "Jane"; // 可以修改
delete person.age; // 不会生效
person.gender = "male"; // 不会生效

console.log(person); // { name: "Jane", age: 30 }

Object.is()

比较两个值是否严格相等:

javascript
console.log(Object.is(5, 5)); // true
console.log(Object.is(5, "5")); // false
console.log(Object.is(NaN, NaN)); // true
console.log(Object.is(+0, -0)); // false

对象的继承

JavaScript使用原型链实现继承。

原型继承

javascript
const personPrototype = {
    greet() {
        return "Hello, " + this.name + "!";
    }
};

const employeePrototype = Object.create(personPrototype);
employeePrototype.work = function() {
    return this.name + " is working.";
};

const employee = Object.create(employeePrototype);
employee.name = "John";
employee.position = "Developer";

console.log(employee.greet()); // Hello, John!
console.log(employee.work()); // John is working.

构造函数继承

javascript
function Person(name) {
    this.name = name;
}

Person.prototype.greet = function() {
    return "Hello, " + this.name + "!";
};

function Employee(name, position) {
    Person.call(this, name); // 调用父构造函数
    this.position = position;
}

// 设置原型链
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

Employee.prototype.work = function() {
    return this.name + " is working as " + this.position + ".";
};

const employee = new Employee("John", "Developer");
console.log(employee.greet()); // Hello, John!
console.log(employee.work()); // John is working as Developer.

ES6类继承

使用classextends关键字实现继承:

javascript
class Person {
    constructor(name) {
        this.name = name;
    }
    
    greet() {
        return "Hello, " + this.name + "!";
    }
}

class Employee extends Person {
    constructor(name, position) {
        super(name); // 调用父类构造函数
        this.position = position;
    }
    
    work() {
        return this.name + " is working as " + this.position + ".";
    }
}

const employee = new Employee("John", "Developer");
console.log(employee.greet()); // Hello, John!
console.log(employee.work()); // John is working as Developer.

对象的最佳实践

  1. 使用对象字面量:优先使用对象字面量创建对象
  2. 使用const:使用const声明对象,避免重新赋值
  3. 使用简洁的方法语法:ES6的简洁方法语法使代码更清晰
  4. 避免使用__proto__:使用Object.getPrototypeOf()Object.setPrototypeOf()代替
  5. 使用ES6类:对于复杂的对象关系,使用ES6类语法
  6. 注意this的指向:了解this在不同上下文中的指向

继续学习:JavaScript数组

最后更新:2026-02-08