前言

在 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'

this

在 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); // 输出 25
obj.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']); // 输出 25
obj['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: 'john.doe@example.com'
}; // 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, 'john.doe@example.com'] // Object.entries()
const entries = Object.entries(person);
console.log(entries); // [['firstName', 'John'], ['lastName', 'Doe'], ['age', 30], ['email', 'john.doe@example.com']]

通过这三个方法,我们可以方便地操作对象,快速获取对象的属性、属性值以及属性和属性值的键值对。

小技巧可以通过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 循环遍历对象属性。

深入理解JavaScript对象的更多相关文章

  1. 理解JavaScript对象

    理解JavaScript对象 对象是JavaScript的基本数据类型.对象是一种复合值:将很多值(原始值或者其他对象)聚合在一起. JavaScript对象不仅可以保持自有的属性,还可以从原型对象继 ...

  2. 深入理解javascript对象系列第二篇——属性操作

    × 目录 [1]查询 [2]设置 [3]删除[4]继承 前面的话 对于对象来说,属性操作是绕不开的话题.类似于“增删改查”的基本操作,属性操作分为属性查询.属性设置.属性删除,还包括属性继承.本文是对 ...

  3. 理解javascript 对象,原型对象、闭包

    javascript作为一个面向对象的语言,理解 对象.原型.闭包.模块模式等技术点对于成为一名合格的javascript程序员相当重要,多年没写过blog,今天就先拋个玉,在下基本也不做前端,但颇感 ...

  4. 如何理解javaScript对象?

    在我们生活中,常常会提到对象一词,如:你找到对象了吗?你的对象是谁呀?等等. 在我们家庭中,有男友的女青年都会说我有对象了,那么她的对象是XX(她的男友). 夫妻间呢?都会说我的爱人是谁谁谁,现在我们 ...

  5. JavaScript大杂烩3 - 理解JavaScript对象的封装性

    JavaScript是面向对象的 JavaScript是一种基于对象的语言,你遇到的所有东西,包括字符串,数字,数组,函数等等,都是对象. 面向过程还是面向对象? JavaScript同时兼有的面向过 ...

  6. 深入理解javascript对象系列第三篇——神秘的属性描述符

    × 目录 [1]类型 [2]方法 [3]详述[4]状态 前面的话 对于操作系统中的文件,我们可以驾轻就熟将其设置为只读.隐藏.系统文件或普通文件.于对象来说,属性描述符提供类似的功能,用来描述对象的值 ...

  7. 深入理解javascript对象系列第一篇——初识对象

    × 目录 [1]定义 [2]创建 [3]组成[4]引用[5]方法 前面的话 javascript中的难点是函数.对象和继承,前面已经介绍过函数系列.从本系列开始介绍对象部分,本文是该系列的第一篇——初 ...

  8. 理解 JavaScript 对象原型、原型链如何工作、如何向 prototype 属性添加新的方法。

    JavaScript 常被描述为一种基于原型的语言 (prototype-based language)——每个对象拥有一个原型对象,对象以其原型为模板.从原型继承方法和属性.原型对象也可能拥有原型, ...

  9. JavaScript大杂烩4 - 理解JavaScript对象的继承机制

    JavaScript是单根的完全面向对象的语言 JavaScript是单根的面向对象语言,它只有单一的根Object,所有的其他对象都是直接或者间接的从Object对象继承.而在JavaScript的 ...

  10. 理解Javascript的动态语言特性

    原文:理解Javascript的动态语言特性 理解Javascript的动态语言特性 Javascript是一种解释性语言,而并非编译性,它不能编译成二进制文件. 理解动态执行与闭包的概念 动态执行: ...

随机推荐

  1. 3 c++编程-提高篇-模版

    ​ 重新系统学习c++语言,并将学习过程中的知识在这里抄录.总结.沉淀.同时希望对刷到的朋友有所帮助,一起加油哦!  生命就像一朵花,要拼尽全力绽放!死磕自个儿,身心愉悦!  系列文章列表: 1 c+ ...

  2. day21 单列索引与组合索引 & 索引的优点和使用原则 & 视图与函数

    索引 1.索引有几种 四种,单列索引,组合索引,全文索引,空间索引 2.索引的优点 所有的MySQL数据库列类型都可以被索引,也就是可以给任意字段加索引 提高数据查询速度 索引的缺点 1)创建索引和维 ...

  3. 【Java SE】Day05数组

    一.数组的定义和访问 1.初始化 动态new int[10];--默认值 静态new int[]{1,2,3};,省略为{1,2,3}; 2.访问 长度arr.length属性(数组的属性) 打印数组 ...

  4. 【Java EE】Day04 MySQL多表、事务、事务隔离级别、DCL

    一.多表查询 1.概述 笛卡尔积:两集合的所有组成情况 多表查询:消除笛卡尔积得到的无用数据 2.分类 内连接查询(满足指定条件无空值,只显示有关联的数据) 隐式内连接:使用where限制消除无用数据 ...

  5. MetaTown:一个可以自己构建数字资产的平台

    摘要:华为云Solution as Code重磅推出<基于MetaTown构建数字资产平台>解决方案. 本文分享自华为云社区<基于MetaTown构建数字资产平台>,作者: 阿 ...

  6. 前端开发:4、JavaScript简介、变量与常量、数据类型及内置方法、运算符、流程控制、循环结构、内置方法

    前端开发之JavaScript 目录 前端开发之JavaScript 一.JavaScript简介 二.JS基础 三.变量与常量 四.基本数据类型 1.数值类型 2.字符类型 3.布尔类型 五.特殊数 ...

  7. apache文件工具类的使用:org.apache.commons.io.FileUtils

    说明 org.apache.commons.io.FileUtils 工具类包含了许多操作文件的方法,此文章介绍一些常用的文件操作方法,方便使用的时候查阅参考 创建输入流 public static ...

  8. [py]残留python.exe导致anaconda python路径无法识别

    刚才重下anaconda真是给我整没脾气了 路径啥的都加好了,cmd输入python还是没有,给我跳应用商店去了- 重启也没用 经过一番搜索,找到解决办法: cmd输入"where pyth ...

  9. 【机器学习】李宏毅——Adversarial Attack(对抗攻击)

    研究这个方向的动机,是因为在将神经网络模型应用于实际场景时,它仅仅拥有较高的正确率是不够的,例如在异常检测中.垃圾邮件分类等等场景,那些负类样本也会想尽办法来"欺骗"模型,使模型无 ...

  10. xpath解析数据的方法

    1 功能描述 2 1.实例化一个etree对象,且需要将被解析的页面源码数据加载到该对象中 3 2.调用etree对象中的XPath表达式实现标签的定位和内容捕获 4 3.环境安装 pip insta ...