都2022年了你不会还没搞懂JS Object API吧

简介: JS Object在我们平时的工作中用得并不多,但是也是我们前端必须掌握的一个知识点。今天请跟随笔者的步伐再来温习一遍。

image.png

文章里的每个案例都是我亲自编写并验证的,建议阅读文章时,可以在浏览器执行案例,会更有利于理解。

Object.create(proto,[propertiesObject])

Object.create() 方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__,返回一个新对象,带着指定的原型对象和属性。

注意如果proto参数不是null或非原始包装对象,则抛出一个TypeError异常。

propertiesObject是一个对象,key为属性名,value是一个对象,是该属性的描述符,默认值valueundefinedwritable、enumerable、configurable默认值都是false

const obj = Object.create({msg: '我是原型'}, {name: {
  value: undefined,
  writable: false,
  configurable: false,
  enumerable: false
}})

除了指定value、writable、enumerable、configurable外我们还可以指定get/set方法,如果指定了get/set方法就不能再定义value/writable了,因为它们的意义是一样的。

Object.getOwnPropertyDescriptor(obj, property)

Object.getOwnPropertyDescriptor(obj, property) 方法返回指定对象上一个自有属性对应的属性描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)。

{
  value: "randy", // 属性值
  writable: true, // 是否能修改
  enumerable: true, // 是否枚举 就是能否遍历出来
  configurable: false, // 该属性描述符是否可以被改变并且该属性是否可以被删除
},

writablefalse时不能修改该属性的值。obj.name = 'xxx'Object.defineProperty(obj, "name", {value: 'demi'})都不可以。

enumerablefalse 时,不能进行遍历。

configurablefalse时,属性不能被删除。并且enumerable、configurable不能被修改。writable能改变,但是只能由true改为falsevalue能不能改变由writable决定。

Object.getOwnPropertyDescriptors(obj)

Object.getOwnPropertyDescriptors(obj) 方法用来获取一个对象的所有自身属性的描述符。(自有属性指的是直接赋予该对象的属性,不需要从原型链上进行查找的属性)。

Object.defineProperty(obj, property, propertiesObject)

Object.defineProperty(obj, property, propertiesObject) 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。

Object.defineProperties(obj, propertiesObject)

Object.defineProperties(obj, propertiesObject) 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。

Object.entries(obj)

Object.entries()方法返回一个给定对象自身可枚举属性的键值对数组,其排列与用 for...in循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。

Object.keys(obj)

Object.keys(obj) 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和正常循环遍历该对象时返回的顺序一致 。

Object.values(obj)

Object.values()方法返回一个给定对象自身可枚举属性值的数组,值的顺序与使用for...in循环的顺序相同 (区别在于 for-in 循环枚举原型链中的属性)。

Object.getOwnPropertyNames(obj)

Object.getOwnPropertyNames(obj) 方法返回一个由指定对象的所有自身属性的属性名(包括不可枚举属性,但不包括Symbol值作为名称的属性和原型链上的属性)组成的数组。

Object.getOwnPropertySymbols(obj)

Object.getOwnPropertySymbols(obj) 方法返回一个给定对象自身的所有Symbol属性的数组。并且不管该Symbol属性是否是可枚举,都能遍历出来。

obj.hasOwnProperty(prop)

obj.hasOwnProperty(prop) 方法会返回一个布尔值,指示对象自身属性中是否具有指定的属性(也就是,是否有指定的键)。

这个方法可以用来检测一个对象是否含有特定的自身属性;和 in 运算符不同,该方法会忽略掉那些从原型链上继承到的属性。

obj.propertyIsEnumerable(prop)

obj.propertyIsEnumerable(prop) 方法返回一个布尔值,表示指定的属性是否可枚举。

Object.getPrototypeOf(obj)

Object.getPrototypeOf() 方法返回指定对象的原型(内部[[Prototype]]属性的值)。

obj1.isPrototypeOf(obj2)

isPrototypeOf() 方法用于测试一个对象是否是另一个对象的原型。

isPrototypeOf() 与 instanceof运算符不同。isPrototypeOf()是直接判断,而instanceof会通过原型链层层递归判断。

Object.setPrototypeOf(obj, prototype)

Object.setPrototypeOf(obj, prototype)方法设置一个指定的对象的原型 ( 即内部[[Prototype]]属性)`。

实例1

const proto = { msg: "原型" };

const obj = Object.create(proto, {
  // value的默认值是undefined,writable、enumerable、configurable、默认值都是false
  name: {
    // value: "randy", // 属性值
    // writable: true, // 是否能修改
    // enumerable: true, // 是否枚举 就是能否遍历出来
    // configurable: true, // 该属性描述符是否可以被改变并且该属性是否可以被删除
  },
  [Symbol("a")]: {
    // value: "symboltest",
    // writable: true,
    // enumerable: true,
    // configurable: true,
  },
});

// 这种赋值方式 writable、enumerable、configurable、默认值都是true
obj.age = 24;

console.log(obj); // {age: 24, name: undefined, Symbol(a): undefined}
// Object.getOwnPropertyDescriptor() 方法返回指定对象上一个自有属性对应的属性描述符。
console.log(Object.getOwnPropertyDescriptor(obj, "name")); // {configurable: false,enumerable: false,value: undefined,writable: false}
// Object.getOwnPropertyDescriptors() 方法用来获取一个对象的所有自身属性的描述符。
// age: {value: 24, writable: true, enumerable: true, configurable: true}
// name: {value: undefined, writable: false, enumerable: false, configurable: false}
// Symbol(a): {value: undefined, writable: false, enumerable: false, configurable: false}
console.log(Object.getOwnPropertyDescriptors(obj));

// writable为false的情况下 修改无效
obj.name = "demi";
// configurable 为false的情况下 删除无效
// delete obj.name;

// Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
// configurable 为false的情况下 会报错
// Object.defineProperty(obj, "name", {
//   writable: true,
// });

// Object.defineProperties() 方法直接在一个对象上定义新的属性或修改现有属性,并返回该对象。
// configurable 为false的情况下 会报错
// Object.defineProperties(obj, {
//   name: {
//     writable: true,
//   }
// });

// enumerable为true的情况下 才能进行遍历
Object.keys(obj).forEach((key) => {
  console.log("key:", key); // age
});
Object.values(obj).forEach((value) => {
  console.log("value:", value); // 24
});
Object.entries(obj).forEach((entry) => {
  console.log("entry:", entry); // [age, 24];
});
// 该方法例外 能遍历不可枚举属性 但是不包括Symbol 属性
Object.getOwnPropertyNames(obj).forEach((name) => {
  console.log("name:", name); // name age
});
// 并且不管该`Symbol`属性是否是可枚举,都能遍历出来。
Object.getOwnPropertySymbols(obj).forEach((symbolKey) => {
  console.log("symbol:", symbolKey); // Symbol(a)
});

// 是否拥有某属性
console.log(obj.hasOwnProperty("name")); // true
console.log(obj.hasOwnProperty("msg")); // false

// 是否可枚举
console.log(obj.propertyIsEnumerable("name")); // false

// 获取原型
console.log(Object.getPrototypeOf(obj)); // {msg: '原型'}

// 某对象是否是某对象的原型
console.log(proto.isPrototypeOf(obj)); // true

// 设置更新原型
Object.setPrototypeOf(obj, null);
console.log(Object.getPrototypeOf(obj)); // null

console.log(obj); // {age: 24, name: undefined, Symbol(a): undefined}

Object.seal(obj)

Object.seal(obj)方法封闭一个对象,阻止添加新属性并将所有现有属性标记为不可配置。当前属性的值只要原来是可写的就可以改变。

也就是将configurable置为了false。只能修改已有属性和遍历。不能修改描述符和删除属性。

Object.isSealed(obj)

Object.isSealed(obj)方法判断一个对象是否被密封。

Object.isExtensible(obj)

Object.isExtensible() 方法判断一个对象是否是可扩展的(是否可以在它上面添加新的属性)。

实例2

const obj6 = { name: "demi" };
// {name: {value: 'demi', writable: true, enumerable: true, configurable: true}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj6)
);
console.log("isSealed: ", Object.isSealed(obj6)); // false
// 对对象进行密封
Object.seal(obj6);
console.log("isSealed: ", Object.isSealed(obj6)); // true
// {name: {value: 'demi', writable: true, enumerable: true, configurable: false}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj6)
);
// configurable置为了false 所以不能修改该对象已有属性的可枚举性、可配置性,也不能删除已有属性
// 可写性writable只能由true变为false
// Object.defineProperty(obj6, "name", {
//   writable: false,
//   enumerable: false,
//   configurable: false,
// });
delete obj6.name; // 不能删除值
obj6.phone = "17673485272"; // 不能添加新属性
obj6.name = "randy"; // 能修改以前是可写的值

console.log("seal: ", obj6); // {name: 'randy'}

// false
console.log(
  "isExtensible: ",
  Object.isExtensible(obj6),
  "密封的对象不能扩展"
);

Object.freeze(obj)

Object.freeze() 方法可以冻结一个对象。一个被冻结的对象再也不能被修改;冻结了一个对象则不能向这个对象添加新的属性,不能删除已有属性,不能修改该对象已有属性的可枚举性、可配置性、可写性,以及不能修改已有属性的值。此外,冻结一个对象后该对象的原型也不能被修改。

也就是将configurablewritable置为了false。只能遍历。

Object.isFrozen(obj)

Object.isFrozen(obj)方法判断一个对象是否被冻结。

实例3

const obj5 = { name: "demi" };
// {name: {value: 'demi', writable: true, enumerable: true, configurable: true}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj5)
);
console.log("isFrozen: ", Object.isFrozen(obj5)); // false
// 冻结
Object.freeze(obj5);
console.log("isFrozen: ", Object.isFrozen(obj5)); // true
// {name: {value: 'demi', writable: false, enumerable: true, configurable: false}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj5)
);
obj5.age = 25; // 不能添加属性
obj5.name = "randy"; // 不能修改属性
delete obj5.name; // 不能删除属性
// configurable置为了false 不能修改该对象已有属性的可枚举性、可配置性、可写性,也不能删除已有属性
// Object.defineProperty(obj5, "name", {
//   writable: false,
//   enumerable: false,
//   configurable: false,
// });
console.log("freeze: ", obj5); // {name: 'demi'}

// false
console.log(
  "isExtensible: ",
  Object.isExtensible(obj5),
  "冻结的对象不能扩展"
);

Object.assign(target, ...sources)

这个方法在笔者前面的文章赋值拷贝、浅拷贝、深拷贝已经介绍过了,该方法是一个浅拷贝方法,并且会改变原对象。

Object.assign(target, ...sources) 方法用于将所有可枚举属性的值从一个或多个源对象分配到目标对象。它将返回目标对象。

如果目标对象中的属性具有相同的键,则属性将被源对象中的属性覆盖。后面的源对象的属性将类似地覆盖前面的源对象的属性。

实例4

const obj2 = { name: "demi", phone: "17673485272" };
const obj3 = { name: "tom", address: "上海" };
const obj4 = { name: "jack", age: 24 };
console.log(Object.assign(obj2, obj3, obj4)); // {name: 'jack', phone: '17673485272', address: '上海', age: 24}
console.log(obj2); // {name: 'jack', phone: '17673485272', address: '上海', age: 24}

Object.preventExtensions(obj)

Object.preventExtensions()方法让一个对象变的不可扩展,也就是永远不能再添加新的属性。

该方法只是控制对象不能再添加新属性,并不会像密封、冻结一样修改属性描述符。

实例5

const obj7 = { name: "amy" };
// {name: {value: 'amy', writable: true, enumerable: true, configurable: true}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj7)
);
Object.preventExtensions(obj7);
// {name: {value: 'amy', writable: true, enumerable: true, configurable: true}}
console.log(
  "getOwnPropertyDescriptors: ",
  Object.getOwnPropertyDescriptors(obj7)
);

obj7.age = 24; // 不能新增
obj7.name = "amy2"; //能修改
// delete obj7.name; //能删除

console.log(
  "preventExtensions isExtensible: ",
  Object.isExtensible(obj7),
  "阻止对象扩展后,对象不能扩展"
); // false

console.log("preventExtensions: ", obj7); // {name: 'amy2'}

Object.fromEntries(entries)

Object.fromEntries(entries) 方法把键值对列表转换为一个对象。

实例6

const entries = new Map([
  ['name', 'randy'],
  ['age', 24]
]);

const obj8 = Object.fromEntries(entries);

console.log(obj8); // { name: "randy", age: 24 }

系列文章

都2022年了你不会还没搞懂JS数据类型吧

都2022年了你不会还没搞懂JS原型和继承吧

都2022年了你不会还没搞懂JS赋值拷贝、浅拷贝、深拷贝吧

都2022年了你不会还没搞懂对象数组的遍历吧

都2022年了你不会还没搞懂this吧

都2022年了你不会还没搞懂JS Object API吧

都2022年了你不会还没搞懂js垃圾回收和内存泄露吧

都2022年你不会还没搞懂js执行上下文和事件循环机制吧

都2022年了你不会还没搞懂js中的事件吧

都2020年了你不会还没搞懂js异步编程吧

参考文章

MDN Object章节

后记

感谢小伙伴们的耐心观看,本文为笔者个人学习笔记,如有谬误,还请告知,万分感谢!如果本文对你有所帮助,还请点个关注点个赞~,您的支持是笔者不断更新的动力!

相关文章
|
8月前
|
前端开发 JavaScript NoSQL
使用 Node.js、Express 和 React 构建强大的 API
本文详细介绍如何使用 Node.js、Express 和 React 构建强大且动态的 API。从开发环境搭建到集成 React 前端,再到利用 APIPost 高效测试 API,适合各水平开发者。内容涵盖 Node.js 运行时、Express 框架与 React 库的基础知识及协同工作方式,还涉及数据库连接和前后端数据交互。通过实际代码示例,助你快速上手并优化应用性能。
|
12月前
|
编解码 人工智能 缓存
自学记录鸿蒙API 13:实现多目标识别Object Detection
多目标识别技术广泛应用于动物识别、智能相册分类和工业检测等领域。本文通过学习HarmonyOS的Object Detection API(API 13),详细介绍了如何实现一个多目标识别应用,涵盖从项目初始化、核心功能实现到用户界面设计的全过程。重点探讨了目标类别识别、边界框生成、高精度置信度等关键功能,并分享了性能优化与功能扩展的经验。最后,作者总结了学习心得,并展望了未来结合语音助手等创新应用的可能性。如果你对多目标识别感兴趣,不妨从基础功能开始,逐步实现自己的创意。
359 60
|
9月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
JSON 缓存 JavaScript
深入浅出:使用Node.js构建RESTful API
在这个数字时代,API已成为软件开发的基石之一。本文旨在引导初学者通过Node.js和Express框架快速搭建一个功能完备的RESTful API。我们将从零开始,逐步深入,不仅涉及代码编写,还包括设计原则、最佳实践及调试技巧。无论你是初探后端开发,还是希望扩展你的技术栈,这篇文章都将是你的理想指南。
|
11月前
|
JavaScript 前端开发 安全
盘点原生JS中目前最没用的几个功能API
在JavaScript的发展历程中,许多功能与API曾风光无限,但随着技术进步和语言演化,部分功能逐渐被淘汰或被更高效的替代方案取代。例如,`with`语句使代码作用域复杂、可读性差;`void`操作符功能冗余且影响可读性;`eval`函数存在严重安全风险和性能问题;`unescape`和`escape`函数已被`decodeURIComponent`和`encodeURIComponent`取代;`arguments`对象则被ES6的剩余参数语法替代。这些变化体现了JavaScript不断优化的趋势,开发者应紧跟技术步伐,学习新技能,适应新技术环境。
208 10
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
270 12
|
JavaScript NoSQL API
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发如同一座灯塔,指引着数据的海洋。本文将带你航行在Node.js的海域,探索如何从一张白纸到完成一个功能完备的RESTful API。我们将一起学习如何搭建开发环境、设计API结构、处理数据请求与响应,以及实现数据库交互。准备好了吗?启航吧!
|
前端开发 JavaScript API
【百度地图API】JS版本的常见问题
原文:【百度地图API】JS版本的常见问题 【新手必读】API常见问题   2011-12-12   1、请问如何将我的店铺标注在百度地图上?我是否可以做区域代理?在百度地图上标注是否免费?   答复: 这里只负责API的技术咨询,不解决任何地图标注问题。
2687 0
|
2月前
|
缓存 监控 前端开发
顺企网 API 开发实战:搜索 / 详情接口从 0 到 1 落地(附 Elasticsearch 优化 + 错误速查)
企业API开发常陷参数、缓存、错误处理三大坑?本指南拆解顺企网双接口全流程,涵盖搜索优化、签名验证、限流应对,附可复用代码与错误速查表,助你2小时高效搞定开发,提升响应速度与稳定性。
|
2月前
|
JSON 算法 API
Python采集淘宝商品评论API接口及JSON数据返回全程指南
Python采集淘宝商品评论API接口及JSON数据返回全程指南

热门文章

最新文章