2

深入理解JavaScript对象 - CodeForBetter

 1 year ago
source link: https://www.cnblogs.com/pglin/p/17140678.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

在 JavaScript 中,对象是一种非常常见的数据类型,几乎每个程序员都会在日常工作中频繁地使用对象。在本篇文章中,我们将深入了解 JavaScript 对象的一些基本概念和一些高级概念,这些概念对于我们正确理解对象在 JavaScript 中的行为非常重要。

对象的基本概念

在 JavaScript 中,对象是由键值对组成的集合。键是一个字符串或者 Symbol 类型的值,值可以是任何类型的数据,包括其他对象。对象是一种动态数据结构,可以通过添加、删除或修改属性来改变对象的状态。以下是 JavaScript 中定义对象的一些基本语法:

const myObj = { key1: 'value1', key2: 'value2', key3: 'value3',};

在这个对象中,每一个键都有一个相应的值。可以使用点操作符或方括号操作符来访问对象的属性:

console.log(myObj.key1); // 输出 'value1'console.log(myObj['key2']); // 输出 'value2'

可以通过以下方式向对象添加新的属性:

myObj.newKey = 'newValue';console.log(myObj.newKey); // 输出 'newValue'

对象也可以作为函数的参数和返回值:

function createObj() { return { key1: 'value1', key2: 'value2', key3: 'value3' };} const obj = createObj();console.log(obj.key1); // 输出 'value1'

对象的高级概念-原型

在 JavaScript 中,对象之间可以有一种原型关系,即一个对象可以继承另一个对象的属性和方法。每一个对象都有一个原型对象,它是另一个对象的引用,可以通过 Object.getPrototypeOf(obj) 来访问。

在 JavaScript 中,有两种方式来创建一个新对象:

  • 使用对象字面量 {} 或者 new Object() 来创建一个空对象。
  • 使用构造函数来创建一个对象。

构造函数可以使用 new 关键字来调用,它会创建一个新的对象并把这个对象的原型设置为构造函数的 prototype 属性。
在后一种方式中,可以通过构造函数的 prototype 属性来为新对象添加方法和属性。新创建的对象会继承构造函数的原型,因此可以访问这些方法和属性。以下是一个简单的例子:

function MyObj() { this.name = 'My Object';} MyObj.prototype.getName = function () { return this.name;}; const obj = new MyObj();console.log(obj.getName()); // 输出 'My Object'

在 JavaScript 中,this 关键字指的是当前正在执行的函数的上下文对象。在对象中,this 指向该对象本身。例如:

const myObj = { name: 'My Object', getName: function () { return this.name; },}; console.log(myObj.getName()); // 输出 'My Object'

JS对象的创建和访问

在JS中,对象是一种复合值,包含了无数个属性(key-value pairs),它可以是字符串、数字、布尔值、数组或者其他对象等等。对象是JS中最重要的数据结构之一。

对象的创建

对象字面量

最常见的创建对象的方法是使用对象字面量。对象字面量是一个由若干键值对组成的对象。这种方式创建的对象可以直接使用{}来表示,也可以使用一个变量来存储这个对象。

const person = { name: 'Alice', age: 18, gender: 'female' };

对象字面量创建的对象可以直接在定义时添加属性,也可以后期添加。

const person = {};person.name = 'Alice';person.age = 18;person.gender = 'female';

Object构造函数

除了对象字面量之外,还可以使用Object构造函数来创建对象。可以使用new关键字和Object构造函数创建一个空对象,或者将一个现有对象作为参数传递给Object构造函数来创建一个与该对象相同的新对象。

const emptyObj = new Object();const person = new Object({ name: 'Alice', age: 18, gender: 'female' });

工厂函数是一个返回对象的函数。它们通过抽象化对象的创建和初始化来降低重复代码的量。当需要创建多个类似的对象时,可以使用工厂函数来代替每个对象都写一遍相同的代码。

function createPerson(name, age, gender) { return { name, age, gender };} const person1 = createPerson('Alice', 18, 'female');const person2 = createPerson('Bob', 20, 'male');

构造函数是一种特殊的函数,用于创建并初始化一个由该类型定义的对象。当我们使用new关键字创建对象时,实际上是在调用构造函数。

function Person(name, age, gender) { this.name = name; this.age = age; this.gender = gender;} const person1 = new Person('Alice', 18, 'female');const person2 = new Person('Bob', 20, 'male');

class

ES6引入了class语法,让JS的面向对象编程更加直观和易于理解。使用class创建对象的语法如下:

class Person { constructor(name, age, gender) { this.name = name; this.age = age; this.gender = gender; }} const person1 = new Person('Alice', 18, 'female');const person2 = new Person('Bob', 20, 'male');

访问对象的属性

访问 JS 对象的属性和方法通常有两种方式:点语法和方括号语法。
使用点语法,可以通过对象名称后面跟随一个句点,然后是属性名,来访问对象的属性和方法,例如:

const obj = { name: 'Alice', age: 25, sayHello() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); }}; console.log(obj.name); // 输出 'Alice'console.log(obj.age); // 输出 25obj.sayHello(); // 输出 'Hello, my name is Alice and I am 25 years old.'

使用方括号语法,可以通过对象名称后面跟随一个方括号,里面是属性名或者变量名,来访问对象的属性和方法,例如:

const obj = { name: 'Alice', age: 25, sayHello() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); }}; console.log(obj['name']); // 输出 'Alice'console.log(obj['age']); // 输出 25obj['sayHello'](); // 输出 'Hello, my name is Alice and I am 25 years old.'

使用方括号语法时,可以在方括号中使用表达式,例如:

const obj = { name: 'Alice', age: 25, sayHello() { console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`); }}; const propName = 'name';console.log(obj[propName]); // 输出 'Alice' const method = 'sayHello';obj[method](); // 输出 'Hello, my name is Alice and I am 25 years old.'

需要注意的是,在方括号语法中,属性名或者变量名必须用引号括起来,否则会被解释为变量名。另外,在使用方括号语法访问对象的属性和方法时,可以使用变量名,这个变量名可以在运行时决定。

总的来说,访问 JS 对象的属性和方法是非常简单的,但是需要注意使用点语法和方括号语法的区别,以及在使用方括号语法时需要注意属性名或者变量名的引号问题。

对象的遍历

遍历对象是很常见的操作。对象的遍历可以使用 for-in 循环,也可以使用 Object.keys() 方法遍历对象的键名。

const obj = { name: 'Tom', age: 18, gender: 'male' }; // 使用 for-in 循环遍历对象for (let key in obj) { console.log(key, obj[key]);} // 使用 Object.keys() 方法遍历对象的键名Object.keys(obj).forEach(key => { console.log(key, obj[key]);});

对象常用的三个方法

Object.keys(), Object.values(), 和 Object.entries() 都是用于操作对象的方法。

  • Object.keys(obj):返回一个由给定对象的所有可枚举自身属性的属性名组成的数组。
  • Object.values(obj):返回一个给定对象的所有可枚举自身属性的属性值组成的数组。
  • Object.entries(obj):返回一个给定对象自身可枚举属性的键值对数组。

下面我们举个例子来说明这三个方法的使用:

const person = { firstName: 'John', lastName: 'Doe', age: 30, email: '[email protected]'}; // Object.keys()const keys = Object.keys(person);console.log(keys); // ['firstName', 'lastName', 'age', 'email'] // Object.values()const values = Object.values(person);console.log(values); // ['John', 'Doe', 30, '[email protected]'] // Object.entries()const entries = Object.entries(person);console.log(entries); // [['firstName', 'John'], ['lastName', 'Doe'], ['age', 30], ['email', '[email protected]']]

通过这三个方法,我们可以方便地操作对象,快速获取对象的属性、属性值以及属性和属性值的键值对。
小技巧可以通过Object.entries()方便的将对象转为Map类型。

对象的拷贝

在 JavaScript 中,对象的赋值是浅拷贝,即只会拷贝对象的引用。如果需要实现对象的深拷贝,则需要使用一些特殊的方法。

浅拷贝只是将对象的引用拷贝给了另一个对象,因此在修改原对象时,拷贝对象也会发生变化。

const obj1 = { name: 'Tom', age: 18 };const obj2 = obj1; obj1.age = 20; console.log(obj1); // { name: 'Tom', age: 20 }console.log(obj2); // { name: 'Tom', age: 20 }

Object.assign()

该方法可以将多个对象合并为一个对象,实现浅拷贝。

const obj1 = { name: 'Tom', age: 18 };const obj2 = { gender: 'male' };const obj3 = Object.assign({}, obj1, obj2); console.log(obj3); // { name: 'Tom', age: 18, gender: 'male' }

使用深拷贝创建的对象,对其进行操作不会影响原有对象。实现对象的深拷贝需要使用一些特殊的方法。常见的深拷贝方法有 JSON.parse(JSON.stringify()) 和递归拷贝两种方法。

JSON.parse(JSON.stringify())

JSON.parse(JSON.stringify()) 方法可以实现深拷贝,但是只能处理对象中的原始类型,不能处理函数、正则表达式等类型。

const obj1 = { name: 'Tom', age: 18, hobbies: ['reading', 'music'] };const obj2 = JSON.parse(JSON.stringify(obj1)); obj1.hobbies.push('travel'); console.log(obj1); // { name: 'Tom', age: 18, hobbies: [ 'reading', 'music', 'travel' ] }console.log(obj2); // { name: 'Tom', age: 18, hobbies: [ 'reading', 'music' ] }

递归拷贝可以处理任何类型的数据,包括函数、正则表达式等。在拷贝对象时,需要递归遍历对象的属性,并将属性值进行拷贝。

function deepClone(obj) { // 判断是否为对象或数组 if (typeof obj !== 'object' || obj === null) { return obj; } // 判断是数组还是对象 const newObj = Array.isArray(obj) ? [] : {}; // 遍历对象或数组 for (let key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = deepCopy(obj[key]); } }

还可用第三方库Lodash实现深浅拷贝。

在 JavaScript 中,对象是由键值对组成的集合,每个键值对就是对象的一个属性,属性名是键,属性值可以是任何数据类型,包括基本类型、对象类型和函数类型等。对象可以通过字面量、构造函数以及 Object.create() 方法创建,也可以通过 Object.defineProperty() 方法定义属性的 getter 和 setter。

JavaScript 的对象具有动态性,可以随时添加或删除属性,也可以改变属性的值。通过使用“点”或“中括号”语法可以访问和修改对象的属性值。此外,可以使用 Object.keys()、Object.values()、Object.entries() 等方法来遍历对象的属性,也可以使用 for...in 和 for...of 循环遍历对象属性。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK