对象定义
JavaScript 对象:核心概念
Section titled “JavaScript 对象:核心概念”对象是 JavaScript 的基础。理解它们是掌握这门语言的关键。
| 在 JavaScript 中,对象是键值对的集合。这些对通常被称为属性。 |
|---|
虽然 JavaScript 有原始数据类型(如字符串、数字、布尔值),但几乎所有其他东西都表现得像对象,或者可以通过包装对象暂时视为对象。
- 原始值(string、number、boolean、null、undefined、symbol、bigint)本身不是对象,但 string、number 和 boolean 原始值有相应的对象包装器(
String、Number、Boolean),它们提供方法。 - 日期始终是对象(
Date)。 Math是一个内置的全局对象,具有静态属性和方法(Math)。- 正则表达式是对象(
RegExp)。 - 数组是一种特殊类型的对象。
- 函数是第一等对象。
- 当然,你创建的自定义对象也是对象。
JavaScript 的原始值是不可变的,而对象是可变的。
对象:包含键控集合的变量
Section titled “对象:包含键控集合的变量”一个简单的变量只持有一个值:
let personName = "John Doe"; // 一个字符串原始值然而,对象可以容纳许多值,这些值通过键(名称)组织起来。这些键值对称为属性。
const person = { firstName: "John", lastName: "Doe", age: 50, eyeColor: "blue"};| 一个 JavaScript 对象是属性的集合,其中每个属性都有一个名称(键)和一个值。 |
|---|
JavaScript 对象中命名的值称为属性。键通常是字符串(或 Symbols),值可以是任何数据类型,包括其他对象或函数。
对于上面的 person 对象:
| 属性键 | 属性值 |
|---|---|
| firstName | ”John” |
| lastName | ”Doe” |
| age | 50 |
| eyeColor | ”blue” |
这种键值结构类似于:
- Python 中的字典 (Dictionaries)
- Java 和 C# 中的哈希映射 (Hash maps) 或哈希表 (Hash tables)
- PHP 中的关联数组 (Associative arrays)
- Ruby 和 Perl 中的哈希 (Hashes)
方法是作为对象属性存储的函数。它们定义了可以在对象上或由对象执行的操作。
const personWithMethod = { firstName: "Jane", lastName: "Doe", age: 30, eyeColor: "green", fullName: function() { return this.firstName + " " + this.lastName; }, // ES6 简写方法语法 greet() { console.log("Hello, my name is " + this.fullName()); }};
console.log(personWithMethod.fullName()); // 输出: Jane DoepersonWithMethod.greet(); // 输出: Hello, my name is Jane Doe| JavaScript 对象是属性的动态集合,其中一些属性可以是方法(函数)。 |
|---|
在后续章节中,你将学习更多关于函数和 this 关键字的知识。
创建 JavaScript 对象
Section titled “创建 JavaScript 对象”在 JavaScript 中,有几种创建对象的方法:
- 对象字面量 (Object Literal): 最简单、最常见的方式。
- 构造函数 (Constructor Functions): 创建多个相同类型对象的传统方式。
- ES6 类 (ES6 Classes): 创建对象和实现继承的现代语法(它是构造函数和原型的语法糖)。
- 使用
new Object(): 通常不推荐,更倾向于使用对象字面量。 - 使用
Object.create(): 创建一个具有指定原型对象的新对象。
使用对象字面量
Section titled “使用对象字面量”这是最直接的方法。你可以在一个语句中定义并创建一个对象。
const car = { make: "Toyota", model: "Camry", year: 2021, startEngine() { console.log("Engine started!"); // 引擎启动! }};使用构造函数(ES6 之前的风格)
Section titled “使用构造函数(ES6 之前的风格)”构造函数用于创建多个具有相同结构和行为的对象。
function Person(first, last, age, eye) { this.firstName = first; this.lastName = last; this.age = age; this.eyeColor = eye; this.describe = function() { return `${this.firstName} ${this.lastName}, ${this.age} years old.`; };}
const myFather = new Person("John", "Doe", 50, "blue");const myMother = new Person("Sally", "Rally", 48, "green");
console.log(myFather.describe()); // John Doe, 50 岁。使用 ES6 类(现代方法)
Section titled “使用 ES6 类(现代方法)”ES6 类为创建对象和处理继承提供了更清晰的语法。它们是 JavaScript 现有基于原型的继承的语法糖。
class Vehicle { constructor(make, model, year) { this.make = make; this.model = model; this.year = year; }
getInfo() { return `${this.year} ${this.make} ${this.model}`; }}
const myCar = new Vehicle("Honda", "Civic", 2022);console.log(myCar.getInfo()); // 2022 本田 思域| 对于简单的、一次性使用的对象,首选对象字面量。对于创建多个相似对象的蓝图,ES6 类是现代标准方法,但了解构造函数对于理解旧代码库或更深层的 JavaScript 概念很有帮助。 |
|---|
this 关键字
Section titled “this 关键字”在 JavaScript 中,this 指向当前正在执行代码的对象。它的值取决于函数是如何被调用的(调用位置)。
- 在方法中,
this指向所属对象。 - 在普通函数中(不是方法,不是箭头函数),在非严格模式下,
this指向全局对象(浏览器中的window,Node.js 中的global),在严格模式下则指向undefined。 - 在构造函数中(使用
new调用),this指向新创建的实例。 - 在事件处理程序中,
this通常指向接收事件的元素。 - 箭头函数没有自己的
this绑定。它们从其周围的(词法)作用域继承this。
理解 this 至关重要,但也可能很棘手。它的行为是初学者常见的困惑来源。MDN Web Docs 等资源提供了详细解释。
this 是一个关键字,不是变量。它的值不能被重新赋值。 |
|---|
JavaScript 内置构造函数和字面量
Section titled “JavaScript 内置构造函数和字面量”JavaScript 为原生对象提供了内置构造函数,例如 Object、String、Number、Boolean、Array、RegExp、Function、Date。
然而,对于 String、Number、Boolean、Array、Object 和 RegExp,几乎总是最好使用它们的字面量形式,以提高性能和可读性:
// 首选的字面量形式:const obj = {}; // 代替 new Object()const str = "hello"; // 代替 new String("hello")const num = 123; // 代替 new Number(123)const bool = true; // 代替 new Boolean(true)const arr = []; // 代替 new Array()const regex = /pattern/g; // 代替 new RegExp("pattern", "g")
// 函数表达式/声明优于 new Function()const greet = function() { console.log("Hello!"); };
// Date 是一个例外;你必须使用构造函数const today = new Date();Math 对象是一个全局的静态对象;你不需要使用 new 来调用它(例如,Math.random())。
使用像 new String("text") 这样的构造函数会创建一个对象包装器,而不是原始字符串。这可能在比较时导致意外的行为。
JavaScript 对象是可变的
Section titled “JavaScript 对象是可变的”JavaScript 中的对象是引用类型。这意味着当你将一个对象赋给一个变量或将其传递给一个函数时,你处理的是内存中该对象的引用(或指针),而不是对象本身的副本。
const originalPerson = { firstName: "John", lastName: "Doe", age: 50};
const anotherPersonRef = originalPerson; // 两个变量指向同一个对象
anotherPersonRef.age = 55; // 通过一个引用修改会影响原始对象
console.log(originalPerson.age); // 输出: 55 (已改变!)console.log(anotherPersonRef.age); // 输出: 55这与原始类型(字符串、数字、布尔值)不同,原始类型是不可变的,并且通过值复制。
要创建对象的真正副本(无论是浅拷贝还是深拷贝),你需要使用展开语法({...obj} 用于浅拷贝)、Object.assign({}, obj)(浅拷贝)或更复杂的方法/库来进行深拷贝。当你想要修改一个对象而不影响原始对象时,这是一个重要的概念。