前端数据处理(基础篇)对象

本文参考各位大佬的优秀文章,提取其中经常用到的一些方法,记录为笔记,便于自查和复习。文末的参考资料中附上原文链接,便于大家进一步学习。

本篇介绍的是前端数据处理中,对象的相关操作,涉及的内容请看下图:

创建对象

在JavaScript中,对象的键值,既可以是一个函数(称为方法),也可以是基本数据类型(称为属性)。

创建对象的方法有很多种,下面展示几种常见的方法。

对象字面量

使用对象字面量来创建一个对象,这也是开发中经常用到的方式。

javascript 复制代码
 let person = {
   name: 'John',
   age: 30,
   sayHello: function() {
     console.log('Hello!');
   }
 };

构造函数

构造函数允许你定义一个对象模板,然后使用该模板创建多个具有相似结构和行为的对象。因此,当需要创建多个相似的对象时,可以使用这种方式来创建对象。

javascript 复制代码
 function Person(name, age) {
   this.name = name;
   this.age = age;
   this.sayHello = function() {
     console.log('Hello!');
   };
 }
 ​
 let person = new Person('John', 30);

Object 构造函数

javascript 复制代码
 let person = new Object();
 person.name = 'John';
 person.age = 30;
 person.sayHello = function() {
   console.log('Hello!');
 };

上述两种方法的区别:

  • 构造函数是自定义的: 构造函数是由程序员创建的函数,用于创建自定义对象类型。你可以定义构造函数的属性和方法,使其适应特定的需求。
  • Object 构造函数是内建的: Object 是JavaScript的内建构造函数之一,用于创建通用对象。当你使用 new Object() 时,它创建一个空对象。
  • 构造函数可以有自定义行为: 构造函数可以包含自定义的行为,例如在对象创建时执行特定的初始化操作。
  • Object 构造函数相对简单: Object 构造函数相对简单,它主要用于创建基本的空对象,没有额外的自定义行为。

总的来说,构造函数用于创建具有自定义结构和行为的对象,而Object构造函数用于创建基本的空对象。如果只是需要一个简单的空对象,那么使用Object构造函数就足够了。

工厂函数

工厂函数 是一个能返回对象的函数,它既不是类也不是构造函数。在 JavaScript 中,任何函数都可以返回一个对象,如果函数前面没有使用 new 关键字,却又返回一个对象,那这个函数就是一个工厂函数。

javascript 复制代码
 function createPerson(name, age) {
   return {
     name: name,
     age: age,
     sayHello: function() {
       console.log('Hello!');
     }
   };
 }
 ​
 let person = createPerson('John', 30);

属性访问&赋值

在 JavaScript中,几乎所有的事物都是对象。对象包含了属性、方法。

点表示法

点表示法可以用于读取和设置对象的属性值。

点表示法在属性名是合法标识符的情况下更方便。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 // 读取属性值
 console.log(person.name); // 输出: John
 ​
 // 设置属性值
 person.age = 31;
 console.log(person.age); // 输出: 31

对象的方法,可以通过点表示法来访问。通过添加 () 调用 (作为一个函数)。

javascript 复制代码
 var person = {
     fullName: function () {
         console.log("hello");
     }
 };
 person.fullName(); // 输出:hello
 ​
 // 如果不加 ()
 console.log(person.fullName); // 输出:[Function: fullName]
 console.log(typeof person.fullName); // 输出:function

方括号表示法

方括号表示法更灵活,可以处理包含特殊字符或空格的属性名,也可以使用变量作为属性名的引用。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 // 读取属性值
 console.log(person['name']); // 输出: John
 ​
 // 设置属性值
 let propertyName = 'age';
 person[propertyName] = 32;
 console.log(person.age); // 输出: 32

对象的方法,也可以通过方括号表示法来访问。

javascript 复制代码
 var person = {
     fullName: function () {
         console.log("hello");
     }
 };
 person['fullName'](); // 输出:hello

拷贝对象

解构赋值

解构赋值主要用于从对象或数组中提取值,并赋值给变量。

javascript 复制代码
 let person = {};
 ({ name: person.name, age: person.age } = { name: 'John', age: 30 });
 ​
 // 或者简写为:
 let { name, age } = { name: 'John', age: 30 };
 let person = { name, age };

当使用对象解构赋值时,它会创建一个新的对象,其中包含被提取的属性的副本。这是一个浅拷贝的过程,因此对于对象中包含的引用类型(如嵌套对象或数组),它们仍然是原始对象和新对象共享的。

javascript 复制代码
 let originalObject = { name: 'John', age: 30, address: { city: 'New York', zip: '10001' } };
 ​
 // 使用对象解构赋值创建新对象
 let { name, age, address } = originalObject;
 ​
 // 修改新对象的属性值
 name = 'Jane';
 address.city = 'San Francisco';
 ​
 console.log(originalObject); // 输出: { name: 'John', age: 30, address: { city: 'San Francisco', zip: '10001' } }

在上面的例子中,nameage 是原始对象属性的副本,修改它们不会影响原始对象。然而,address 是原始对象中引用类型的属性,因此修改新对象中的 address 属性实际上会影响原始对象,因为它们引用的是相同的对象。

扩展运算符

ES6 的扩展运算符(...)可以用于对象属性的复制,但是,只有第一层是深拷贝,第二层及更深层是浅拷贝。

javascript 复制代码
 let originalObject = { name: 'John', age: 30 };
 ​
 // 使用展开运算符创建对象副本
 let copiedObject = { ...originalObject };
 ​
 // 修改副本的属性值
 copiedObject.name = 'Jane';
 ​
 console.log(originalObject); // 输出: { name: 'John', age: 30 }
 console.log(copiedObject);   // 输出: { name: 'Jane', age: 30 }

Object.assign()

可以使用ES6提供的Object.assign()方法。该方法第一个参数是目标对象,后面为一个或多个源对象。

javascript 复制代码
 let person = {};
 Object.assign(person, { name: 'John', age: 30 });

JSON方法

通过使用 JSON.stringify 将对象转换为 JSON 字符串,然后使用 JSON.parse 将 JSON 字符串转换回对象,可以得到对象的深层次拷贝

但是,这种方法适用于对象中不包含函数、undefined 等不支持 JSON 的特殊值。

javascript 复制代码
 let originalObject = { name: 'John', age: 30, address: { city: 'New York', zip: '10001' } };
 ​
 // 使用 JSON.stringify 将对象转换为 JSON 字符串
 let jsonString = JSON.stringify(originalObject);
 ​
 // 使用 JSON.parse 将 JSON 字符串转换回对象
 let copiedObject = JSON.parse(jsonString);
 ​
 // 修改副本的属性值
 copiedObject.name = 'Jane';
 copiedObject.address.city = 'San Francisco';
 ​
 console.log(originalObject); // 输出: { name: 'John', age: 30, address: { city: 'New York', zip: '10001' } }
 console.log(copiedObject);   // 输出: { name: 'Jane', age: 30, address: { city: 'San Francisco', zip: '10001' } }

删除属性

在JavaScript中,可以使用 delete 操作符来删除对象的属性。

使用 delete 操作符:

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 // 删除属性
 delete person.age;
 // 或者用方括号表示法
 delete person['age'];
 ​
 console.log(person); // 输出: { name: 'John' }

需要注意的是,使用 delete 删除对象的属性并不会删除对象本身,它只是删除了属性和属性值。删除对象的属性后,该属性将变成 undefined。如果属性不存在,则 delete 操作不会报错,而是返回 true

javascript 复制代码
 let person = { name: 'John' };
 ​
 // 删除不存在的属性,不会报错
 let result = delete person.age;
 ​
 console.log(result);   // 输出: true
 console.log(person);   // 输出: { name: 'John' }
 console.log(person.age);// 输出: undefined

需要注意的是,有些情况下,使用 delete 可能并不是最佳的选择。在某些情况下,更好的做法是将属性值设置为 nullundefined,以保留属性,但将其值清空。


判断对象中是否含有某个属性

这在开发中经常会遇到,若对象中某个属性不存在,但是代码中引用了,那么就会报错!

对象.属性 + undefined

  • 通过点或者方括号可以获取对象的属性值,如果对象上不存在该属性,则会返回 undefined
  • 这种方式可以判断指定对象的自有属性和继承属性,如果对象自身没有检测的属性,而原型链上有该属性,则会返回原型链上的属性值。
javascript 复制代码
 // 创建对象
 let obj = {
     name: 'Scarlett',
     age: 37
 }
 console.log(obj.name !== undefined)  // true 自身属性存在
 console.log(obj['name'] !== undefined)  // true
 console.log(obj.gender)  // 输出:undefined
 ​
 // 在原型上添加一个可枚举属性
 Object.prototype.nationality = 'America'
 ​
 // 在obj对象上添加一个不可枚举属性
 Object.defineProperty(obj, 'occupation', {
     value: 'actress',
     enumerable: false
 })
 ​
 console.log(obj.nationality !== undefined) // true
 console.log(obj['occupation'] !== undefined)  // true

in 运算符

上述使用undefined方法判断,存在一个缺点:属性名存在,属性值为 undefined 的情况下,就不能返回想要的结果。

javascript 复制代码
 let obj = {}
 // 新增一个值为undefined的属性
 obj.birthday = undefined
 console.log(obj.birthday)  // undefined
 console.log(obj.birthday !== undefined)  // false

这个时候,就需要用到 in 运算符

  • in运算符希望它的左操作数是一个字符串或可以转换为字符串,希望它的右侧操作数是一个对象。
  • 可以判断指定对象的自有属性和继承属性中是否存在某属性,如果存在则返回 true。 in 运算符也能检测到原型链上的属性。
  • 值为 undefined 的属性也可以正常判断
javascript 复制代码
 let obj = {
     name: 'Scarlett',
     age: 37
 }
 // 新增一个值为undefined的属性
 obj.birthday = undefined
 ​
 console.log('birthday' in obj); // true
 console.log('name' in obj); // true
 console.log('toString' in obj); // true 继承属性

Object.hasOwnProperty()

hasOwnProperty()用来判断一个对象是否有你给出的名称的属性或对象。有则返回true,没有返回false,

不过需要注意的是,此方法无法检查 该对象的原型链中是否具有该属性,该属性必须是对象本身的一个成员。

javascript 复制代码
 let obj = {
     name: 'Scarlett',
     age: 37
 }
 // 新增一个值为undefined的属性
 obj.birthday = undefined
 ​
 console.log(obj.hasOwnProperty('birthday')); // true
 console.log(obj.hasOwnProperty('name')); // true
 console.log(obj.hasOwnProperty('toString')); // false 继承属性

遍历对象属性

在JavaScript中,有多种方法可以遍历对象。以下是一些常见的遍历对象的方法:

for...in 循环

使用 for...in 循环遍历对象的可枚举属性,包括原型链上的属性。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 for (let key in person) {
   console.log(key, person[key]);
 }
 // 输出:
 // name John
 // age 30

需要注意的是,for...in 循环不仅会遍历对象本身的属性,还会遍历其原型链上的可枚举属性。为了避免遍历原型链上的属性,可以使用 hasOwnProperty 方法进行过滤。

javascript 复制代码
 for (let key in person) {
   if (person.hasOwnProperty(key)) {
     console.log(key, person[key]);
   }
 }

Object.keys() 键

使用 Object.keys() 方法获取对象所有可枚举属性的数组,然后进行遍历。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 console.log(Object.keys(person));
 // 输出:[ 'name', 'age' ]
 ​
 Object.keys(person).forEach(key => {
     console.log(key, person[key]);
 });
 // name John
 // age 30

Object.values() 值

使用 Object.values() 方法获取对象所有可枚举属性的值的数组,然后进行遍历。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 console.log(Object.values(person));
 // 输出:[ 'John', 30 ]

Object.entries() 键&值

使用 Object.entries() 方法获取对象所有可枚举属性的键值对的数组,然后进行遍历。

javascript 复制代码
 let person = { name: 'John', age: 30 };
 ​
 console.log(Object.entries(person));
 // 输出: [ [ 'name', 'John' ], [ 'age', 30 ] ]
 ​
 Object.entries(person).forEach(([key, value]) => {
   console.log(key, value);
 });
 // name John
 // age 30

这些方法可以根据具体的需求选择使用。for...in 循环是最基本的遍历方法,而 Object.keys()Object.values()Object.entries() 提供了更灵活的方式来处理对象的键、值和键值对。

合并对象

Object.assign()

Object.assign()方法既可以用作对象的复制,也可以用于对象的合并。

  • 同名属性会被覆盖
  • Object.assign种第一个值是目标对象,第二个值是源对象
javascript 复制代码
 var o1 = { a: 1 };
 var o2 = { b: 2 };
 var o3 = { c: 3 };
 ​
 var obj = Object.assign(o1, o2, o3);
 console.log(obj); // { a: 1, b: 2, c: 3 }
 console.log(o1);  // { a: 1, b: 2, c: 3 } 注意目标对象自身也会改变。
 ​
 let obj_1 = { name: 'A', age: 37 }
 let obj_2 = { name: 'B', age: 35 }
 console.log(Object.assign(obj_1, obj_2));
 // 输出:{ name: 'B', age: 35 }

扩展运算符

  • 同名属性会被覆盖
  • 使用...扩展运算符合并对象obj1对象在前和在后最后打印的结果是不同的
javascript 复制代码
 let obj_1 = { name: 'A', age: 37 };
 let obj_2 = { name: 'B', age: 35 };
 let result1 = { obj_1, obj_2 }
 let result2 = { ...obj_1, obj_2 }
 let result3 = { ...obj_1, ...obj_2 }
 console.log(result1);
 // 输出:{ obj_1: { name: 'A', age: 37 }, obj_2: { name: 'B', age: 35 } }
 ​
 console.log(result2);
 // 输出:{ name: 'A', age: 37, obj_2: { name: 'B', age: 35 } }
 ​
 console.log(result3);
 // 输出:{ name: 'B', age: 35 }

手写函数

通过手写函数,可以实现对象的合并。

推荐一篇文章:js中合并多个对象的方法 - 掘金 (juejin.cn)

文中通过手写函数实现深拷贝、浅拷贝!

参考资料

有些资料的链接附在文中,有些放在此处:

相关推荐
bysking30 分钟前
【前端-组件】定义行分组的表格表单实现-bysking
前端·react.js
独行soc37 分钟前
#渗透测试#SRC漏洞挖掘#深入挖掘XSS漏洞02之测试流程
web安全·面试·渗透测试·xss·漏洞挖掘·1024程序员节
王哲晓1 小时前
第三十章 章节练习商品列表组件封装
前端·javascript·vue.js
fg_4111 小时前
无网络安装ionic和运行
前端·npm
理想不理想v1 小时前
‌Vue 3相比Vue 2的主要改进‌?
前端·javascript·vue.js·面试
酷酷的阿云1 小时前
不用ECharts!从0到1徒手撸一个Vue3柱状图
前端·javascript·vue.js
微信:137971205871 小时前
web端手机录音
前端
齐 飞1 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
神仙别闹1 小时前
基于tensorflow和flask的本地图片库web图片搜索引擎
前端·flask·tensorflow
aPurpleBerry2 小时前
JS常用数组方法 reduce filter find forEach
javascript