都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章节

后记

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

相关文章
|
9天前
|
JavaScript 前端开发 API
复习JavaScript中的数组API
这段代码介绍了JavaScript数组的几种实用方法:`fill`用于用固定值覆盖指定范围内的元素;`find`查找符合条件的第一个元素;`findIndex`获取该元素的索引;`sort`对数组排序,需提供比较函数以正确排序数字;结合`slice`与`sort`可在不改动原数组的情况下进行排序;`reverse`反转数组元素;利用`map`可创建新数组并替换其中的特定元素,同时保持原数组不变。
8 1
|
4天前
|
缓存 JavaScript 安全
2022年最新最详细的安装Node.js以及cnpm(详细图解过程、绝对成功)
这篇文章提供了2022年最新最详细的Node.js和cnpm安装教程,包括步骤图解、全局配置路径、cnpm安装命令、nrm的安装与使用,以及如何管理npm源和测试速度。
2022年最新最详细的安装Node.js以及cnpm(详细图解过程、绝对成功)
|
6天前
|
存储 JavaScript API
Node.js中的异步API
【8月更文挑战第16天】
13 1
|
9天前
|
XML JavaScript 前端开发
JavaScript中的DOM解析器DOMParser api的讲解
`DOMParser`能将XML或HTML源码字符串解析成DOM `Document`。通过`new DOMParser()`创建实例,使用`.parseFromString(string, type)`方法进行解析,其中`string`为待解析的字符串,`type`指定解析类型如`text/html`或`text/xml`等,返回一个`Document`对象。例如,可解析包含`<p>666</p>`的字符串并获取其文本内容`666`。
13 1
|
1天前
|
JavaScript Linux
2022年超详细在CentOS 7上安装Node.js方法(源码安装)
这篇文章介绍了在CentOS 7系统上通过源码安装Node.js的详细步骤,包括从官网下载Node.js源码包、将安装包上传至虚拟机、解压安装包、删除压缩文件、编译安装Node.js、检查Node.js和npm版本,以及切换npm源到淘宝镜像以加速下载。此外,还提供了一个获取Linux下Node.js离线安装包的微信公众号搜索方式。
|
4天前
|
JavaScript 前端开发 定位技术
百度地图JavaScript API v2.0创建地图
百度地图JavaScript API v2.0创建地图
8 0
|
8天前
|
JavaScript API
复习总结JS中不熟练的API
复习总结JS中不熟练的API
14 0
|
11天前
|
缓存 JavaScript 前端开发
微信 JS-SDK Demo “分享信息设置” API 及数字签名生成方法(NodeJS版本)
微信 JS-SDK Demo “分享信息设置” API 及数字签名生成方法(NodeJS版本)更新时间(2020-10-29)
|
3月前
|
Java
Java Object 类
5月更文挑战第16天
|
6天前
|
前端开发 Java 编译器
【前端学java】java中的Object类和前端中的Object有什么区别(9)
【8月更文挑战第10天】java中的Object类和前端中的Object有什么区别
14 0
【前端学java】java中的Object类和前端中的Object有什么区别(9)

热门文章

最新文章