10 个在 JavaScript 中处理对象的实用函数

本文将着眼于在 JavaScript 中处理对象的最重要的实用函数。
01、Object.freeze
Object.freeze() 冻结一个对象。无法再更改冻结的对象。它返回传入的相同对象。
这是通过在创建时冻结对象来实现 JavaScript 不变性的最简单方法。
const game = Object.freeze({name: 'Warcraft'});game.developer = 'Blizzard';//TypeError: Cannot add property developer, object is not extensible
console.log(Object.isFrozen(game));//true
const game = {name: 'Warcraft',developer: 'Blizzard'};const keys = Object.keys(game);console.log(keys);// ["name", "developer"]
Object.keys(game).forEach(key => console.log(key));
const values = Object.values(game);console.log(values);// ["Warcraft", "Blizzard"]
const game = {name: 'Warcraft',developer: 'Blizzard'};const keyValuePairs = Object.entries(game);console.log(keyValuePairs);// [// ["name", "Warcraft"],// ["developer", "Blizzard"]// ]
Object.entries(game).forEach(([key, value]) => console.log(key, value));//name Warcraft//developer Blizzard
const game = {name: 'Overwatch',developer: {name: 'Blizzard'}};Object.freeze(game);game.developer.name = 'Activision Blizzard';console.log(game);//{// developer: {name: "Activision Blizzard"},// name: "Overwatch"//}
function deepFreeze(object) {Object.entries(object).forEach(([name, value]) => {if (value && typeof value === 'object') {deepFreeze(value);}});return Object.freeze(object);}
deepFreeze(game);game.developer.name = 'Activision Blizzard';//Cannot assign to read only property 'name' of object
const game = {name: 'Warcraft',developer: 'Blizzard'};const map = new Map(Object.entries(game));console.log(map);//Map(2) {"name" => "Warcraft", "developer" => "Blizzard"}
const keyValuePairs = [["name", "Warcraft"],["developer", "Blizzard"]];const game = Object.fromEntries(keyValuePairs);console.log(game);//{name: "Warcraft", developer: "Blizzard"}
const gamePrototype = {toString : function(){return `${this.name}, developed by ${this.developer}`;}};
const game = Object.create(gamePrototype);game.name = "Overwatch";game.developer = "Blizzard";console.log(game.toString());//'Overwatch, developed by Blizzard'
Object.getPrototypeOf(game) === gamePrototype;//true
const obj = {};Object.getPrototypeOf(obj) === Object.prototype;//true
const gameMethods = {toString : function(){return `${this.name}, developed by ${this.developer}`;}};const game = {name: 'Diablo',developer: 'Blizzard'};Object.assign(game, gameMethods);console.log(game.toString());//'Diablo, developed by Blizzard'
我们可以避免修改现有的游戏对象,而是创建一个包含来自现有游戏和 gameMethods 对象的属性的新对象。
我们可以通过将它们的属性复制到一个空对象来做到这一点。
const anotherGame = Object.assign({}, game, gameMethods);console.log(anotherGame.toString());//'Diablo, developed by Blizzard'
如您所见,我们能够使用 Object.assign 和 Object.create 将 toString 方法添加到游戏对象中。
不同之处在于 Object.assign 将属性添加到每个新创建的对象中。Object.create 仅向新创建的对象添加对现有原型的引用。
它不会复制所有可重用的属性。只有在构建数千个对象时才能注意到这种差异。
Object.assign() 也可用于克隆普通对象。
const game = {name: 'Starcraft'};const anotherGame = Object.assign({}, game);console.log(anotherGame);//{name: "Starcraft"}console.log(game === anotherGame);//false
10、Object.defineProperty
Object.defineProperty 实用程序修改现有属性或在对象上定义新属性。它改变并返回修改后的对象。
Object.defineProperty 主要用于设置特定的属性描述符,如可枚举性或定义只读属性。
考虑以下对象。
const game = {name: 'Fornite',developer: 'Epic Games',toString: function(){return `${this.name}, developed by ${this.developer}`;}};Object.keys(game);//["name", "developer", "toString"]
默认情况下,所有新属性都是可枚举的。如您所见,调用 Object.key 实用程序时还返回了 toString 属性名称。
如果我们不希望 toString 成为可枚举属性,我们可以使用 Object.defineProperty 实用程序将其标记为可枚举属性。
Object.defineProperty(game, 'toString', {enumerable: false});console.log(Object.keys(game));//["name", "developer"]
尽管如此,我们可以根据需要更改 toString 属性。
game.toString = undefined;我们通过将 toString 属性上的可写描述符设置为 false 来避免这种行为。
Object.defineProperty(game, 'toString', {enumerable: false,writable: false});game.toString = undefined;//Cannot assign to read only property 'toString' of object
Object.defineProperty 实用程序可用于添加动态 getter 和 setter。
下面是向游戏对象添加动态 getter 的示例。仅当用户有权访问时,getter 才返回属性的值,否则会引发错误。
const game = {name: 'Fornite',developer: 'Epic Games',};const hasRight = false;const propName = "name";Object.defineProperty(game, propName, {get : function () {if(hasRight){return game[propName];} else {throw `${propName} no access`;}}});console.log(game.name);//name no access
重点说明
我们拥有用于冻结和检测冻结对象的实用程序。(Object.freeze / Object.isFrozen)
其他实用程序帮助我们在新数组中提取对象的所有属性,从而使我们能够访问强大的数组方法。(Object.keys / Object.values / Object.entries)
我们可以创建一个继承自现有原型的新对象,然后使用另一个实用程序函数来检查给定对象的原型。(Object.create/Object.getPrototypeOf)
使用 Object.entries 和 Object.fromEntries 助手将对象转换为 [key, value] 对数组,然后再转换回对象变得简单。这使得在地图和对象之间转换变得容易。
Object.assign() 帮助我们克隆对象或将多个对象的属性复制到一个新对象中。
Object.defineProperty 实用程序修改现有属性或定义新属性。它主要用于更改属性描述符。
总结
以上这些内容就是 JavaScript 中处理对象的一些最重要的实用函数。如果您觉得它对您有所帮助,请记得给我点赞,同时,也请您分享给您身边做开发的朋友。
学习更多技能
请点击下方公众号
![]()

