js对象都有什么

admin 104 0
JavaScript对象是复合数据类型,核心由键值对组成,包含属性(数据属性和访问器属性,具writable、enumerable等特性)、原型链(实现属性和方法继承)、方法(作为函数的属性),可通过字面量{}、new Object()、class语法等创建,内置Object、Array等对象提供基础功能,对象支持动态增删属性,是JS中组织复杂数据结构的基础,灵活且强大。

JavaScript对象全解析:从基础到进阶

在JavaScript的宇宙中,**对象是构建一切的基石**,无论是简单的数据存储、复杂的功能实现,还是与DOM、API的深度交互,几乎所有的操作都围绕着对象展开,深刻理解JavaScript对象的构成与特性,是掌握这门语言的核心一步,JavaScript对象这个“全家桶”里究竟装了哪些“珍馐”?本文将从基础到进阶,为您全面拆解JavaScript对象的内在乾坤。

对象的基本定义:键值对的集合

JavaScript中的对象,其本质是**“键值对的集合”**,这里的“键”(Key)必须是字符串(或ES6新增的Symbol类型),“值”(Value)则拥有**无与伦比的包容性**——它可以是任意JavaScript数据类型,包括: * **基本类型**:字符串、数字、布尔值、`null`、`undefined`、Symbol。 * **引用类型**:对象(包括数组、函数、日期、正则表达式等)。

一个典型的用户对象示例,完美体现了这种灵活性:

const user = {
  name: "Alice",       // 键:字符串,值:字符串
  age: 25,             // 键:字符串,值:数字
  hobbies: ["reading", "coding"], // 键:字符串,值:数组(引用类型)
  address: {           // 键:字符串,值:对象(嵌套对象)
    city: "Beijing",
    zip: "100000"
  },
  sayHi: function() {  // 键:字符串,值:函数(对象的方法)
    console.log("Hello, I'm " + this.name);
  }
};

这个“全家桶”示例清晰地展示了,对象的“值”可以构建出任意复杂的数据结构,这正是JavaScript语言灵活性与强大表达力的核心体现。

创建对象的方式:不止一种“姿势”

JavaScript提供了多种创建对象的“姿势”,每种都有其独特的适用场景和优势:

字面量法(最常用、最直观)

直接使用 `{}` 定义对象,是创建简单、结构固定对象的首选方式,简洁高效。

const obj = { key: "value" };

构造函数法(原型继承的基石)

通过 `new` 关键字调用构造函数创建对象,这种方式是**实现“类”的雏形和原型继承**的关键,特别适合创建多个具有相似结构和行为的对象实例。

function Person(name, age) {
  this.name = name; // this 指向新创建的对象实例
  this.age = age;
}
const p1 = new Person("Alice", 25);
const p2 = new Person("Bob", 30);

Object.create()(精确控制原型链)

此方法允许你**显式指定新对象的原型**,是实现原型继承或创建特殊对象(如不继承 `Object.prototype` 的“空对象”)的利器。

const proto = { sayHi: function() { console.log("Hi!"); } };
const obj = Object.create(proto); // obj 的原型链指向 proto
obj.sayHi(); // 输出 "Hi!"

类语法(ES6,面向对象编程的“糖衣”)

ES6 引入的 `class` 关键字是构造函数的**语法糖**,提供了更直观、更接近传统面向对象语言的语法,使代码结构更清晰易读,特别适合构建复杂的类层次结构。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
  sayHi() { // 方法定义在类上(实际添加到原型)
    console.log("Hello, I'm " + this.name);
  }
}
const p = new Person("Charlie", 28);

对象的属性:不止“键值对”那么简单

深入对象的内部,其属性远非简单的“键值对”所能概括,属性分为两大核心类型:**数据属性**和**访问器属性**,每种属性都拥有一组内部特性(Internal Properties),定义了它们的行为,理解这些特性是掌握对象高级用法的关键。

数据属性(Data Properties)

这是最常见的属性类型,直接存储一个值,每个数据属性都包含四个关键特性: * `[[Value]]`: 属性的实际值(默认为 `undefined`)。 * `[[Writable]]`: 是否可以修改属性的值(默认为 `true`)。 * `[[Enumerable]]`: 是否可以通过 `for...in` 循环或 `Object.keys()` 枚举(默认为 `true`)。 * `[[Configurable]]`: 是否可以删除属性或修改其特性(除了 `[[Value]]` 和 `[[Writable]]`)(默认为 `true`)。

**示例:** 我们之前 `user` 对象中的 `name`, `age`, `hobbies` 等都是数据属性。

访问器属性(Accessor Properties)

这类属性不存储值,而是通过一对“访问器函数”来操作值: * `[[Get]]`: 读取属性时调用的函数(getter),默认为 `undefined`。 * `[[Set]]`: 设置属性时调用的函数(setter),默认为 `undefined`。 * `[[Enumerable]]`: 同数据属性(默认为 `true`)。 * `[[Configurable]]`: 同数据属性(默认为 `true`)。

访问器属性非常适合实现**计算属性值、数据验证、或触发副作用**,它们通常通过 `Object.defineProperty()` 或 `Object.defineProperties()` 方法定义。

const temperature = {
  _celsius: 25, // 下划线约定表示“私有”数据(仅约定,非真正私有)
  get celsius() {
    return this._celsius;
  },
  set celsius(value) {
    if (typeof value === 'number') {
      this._celsius = value;
    } else {
      console.error("Temperature must be a number!");
    }
  },
  get fahrenheit() {
    return (this._celsius * 9/5) + 32; // 计算属性
  }
};

console.log(temperature.celsius); // 25 (调用 getter) temperature.celsius = 30; // 调用 setter console.log(temperature.fahrenheit); // 86 (调用 getter 计算值) temperature.celsius = "hot"; // 输出错误信息

标签: #属性 #方法