极简三分钟ES6 - ES8中对象扩展

新增Object.values()和Object.entries()

想象我们管理一个存放水果的仓库(对象)

js 复制代码
const fruitStock = {
  apple: 10,   // 🍎苹果:10箱 
  orange: 15,  // 🍊橙子:15箱
  banana: 8    // 🍌香蕉:8箱 
};

Object.values() :只需清点库存数量(值)

js 复制代码
const stockNumbers = Object.values(fruitStock); 
console.log(stockNumbers);  // [10, 15, 8] → 只关心数量 

Object.entries() :记录完整货品清单(键+值)

js 复制代码
const allRecords = Object.entries(fruitStock); 
console.log(allRecords);  
// [ ["apple", 10], ["orange", 15], ["banana", 8] ] → 完整台账 

一些常见的使用场景

快速提取值集合(Object.values

js 复制代码
// 计算水果总库存 
const total = Object.values(fruitStock).reduce((sum,  num) => sum + num, 0);
console.log(total);  // 33

对象转 Map(Object.entries

js 复制代码
const fruitMap = new Map(Object.entries(fruitStock)); 
console.log(fruitMap.get("orange"));  // 15 → 转为 Map 后查询 

过滤对象属性

js 复制代码
// 找出库存 > 10 的水果
const highStock = Object.entries(fruitStock) 
  .filter(([fruit, count]) => count > 10)
  .map(([fruit]) => fruit);
 
console.log(highStock);  // ["orange"]

替代 for...in 循环

js 复制代码
// 更安全地遍历对象(避免原型污染)
Object.entries(fruitStock).forEach(([fruit,  count]) => {
  console.log(`${fruit}:  ${count}箱`);
});

对象深拷贝技巧

js 复制代码
const copy = Object.fromEntries(Object.entries(fruitStock)); 
console.log(copy);  // {apple:10, orange:15, banana:8} → 全新对象

特殊情况

非对象参数自动转对象

js 复制代码
Object.values("abc");  // ["a", "b", "c"](字符串转包装对象)
Object.entries(42);    // [](数字无属性,返回空数组)

Symbol 属性会被忽略

js 复制代码
const obj = { [Symbol("id")]: 100, name: "test" };
Object.values(obj);    // ["test"] → 跳过 Symbol 
Object.entries(obj);   // [["name", "test"]] 

原型链属性不包含

js 复制代码
function Fruit() { this.type  = "food"; }
Fruit.prototype.color  = "red";
 
const apple = new Fruit();
Object.values(apple);  // ["food"] → 不包含原型属性 

与ES5方案对比

操作需求 ES5 方案 ES8 方案 优势
获取所有值 Object.keys(obj).map(k => obj[k]) Object.values(obj) 代码减少 60%
获取键值对 手动 for...in 循环 Object.entries(obj) 避免原型链污染风险
对象转二维数组 无直接方法 Object.entries(obj) 一行代码完成

选择哪个方法

  • 如下情况使用 Object.values()

    • 统计值总和/平均值
    • 检查值是否满足条件
    • 仅需值集合的场景
  • 如下情况使用 Object.entries()

    • 需同时访问键和值
    • 对象转 Map 或其他数据结构
    • 重构对象属性

Object.getOwnPropertyDescriptors()

对象的"体检报告单"

想象我们要检查一台手机的完整配置

  • 传统方法Object.getOwnPropertyDescriptor() ):只能查单个部件(如摄像头参数)
  • Object.getOwnPropertyDescriptors() :直接生成整机完整参数表(镜头+芯片+屏幕...)
js 复制代码
const phone = {
  brand: "Pixel",
  price: 699,
  get discount() { return this.price  * 0.9 } // getter 计算属性 
};
 
// 获取手机完整配置表
const fullReport = Object.getOwnPropertyDescriptors(phone); 

解决两大痛点

完整复制对象(含 getter/setter)

js 复制代码
const deepCopy = Object.defineProperties( 
  {}, 
  Object.getOwnPropertyDescriptors(phone)  // 保留所有特性
);
deepCopy.price  = 800;
console.log(deepCopy.discount);  // 720(getter 动态计算值)

继承原型方法时不污染目标对象

js 复制代码
// 安全混合对象(不覆盖原型链)
const securityPhone = Object.create( 
  cameraPrototype, // 继承相机功能
  Object.getOwnPropertyDescriptors(phone)  // 添加自有属性 
);

对比其他属性查询方法

方法 作用范围 能否获取 getter/setter 返回结构
Object.keys() 自身可枚举属性 属性名数组
Object.getOwnPropertyNames() 所有自身属性 属性名数组
Object.getOwnPropertyDescriptor() 单个属性 单个描述符对象
Object.getOwnPropertyDescriptors() 所有自身属性 描述符对象集合

一些常见的使用场景

深度克隆对象(保留特性)

js 复制代码
function trueClone(obj) {
  return Object.defineProperties( 
    {}, 
    Object.getOwnPropertyDescriptors(obj) 
  );
}

精确控制类继承

js 复制代码
class PremiumPhone extends Phone {
  constructor() {
    super();
    // 添加会员专属属性(带 getter)
    Object.defineProperties( 
      this, 
      Object.getOwnPropertyDescriptors({ 
        get vipDiscount() { return this.price  * 0.7 }
      })
    );
  }
}

修复 JSON 序列化缺陷

js 复制代码
// JSON.stringify  会忽略 getter!
const phoneJSON = JSON.stringify(phone);  // {brand:"Pixel",price:699}
 
// 通过描述符重建对象 
const restoredPhone = Object.defineProperties( 
  {}, 
  Object.getOwnPropertyDescriptors(phone) 
);

创建不可变对象

js 复制代码
// 锁定所有属性 
const sealedPhone = Object.defineProperties( 
  {}, 
  Object.entries(Object.getOwnPropertyDescriptors(phone)).map(([key,  desc]) => {
    return [key, {...desc, writable: false}] // 全部设为不可写
  })
);
相关推荐
飞天巨兽12 小时前
HTTP基础教程详解
前端·网络·网络协议·http
FIN666812 小时前
昂瑞微IPO前瞻:技术破局高端射频模组,国产替代第二波浪潮下的硬科技突围
前端·科技·搜索引擎·产品运营·创业创新·制造·射频工程
玉树临风江流儿13 小时前
Cmake使用CPack实现打包
java·服务器·前端
xier12345614 小时前
一个全新的react表格组件方案
前端
未来之窗软件服务14 小时前
从东方仙盟筑基期看 JavaScript 动态生成图片技术-东方仙盟
开发语言·javascript·仙盟创梦ide·东方仙盟·图片技术
不叫猫先生15 小时前
中秋连连看小游戏开发完整教程
javascript·css·小游戏·连连看
IT_陈寒15 小时前
5种JavaScript性能优化技巧:从V8引擎原理到实战提速200%
前端·人工智能·后端
蒋星熠15 小时前
Maven项目管理与构建自动化完全指南
java·前端·python·自动化·maven
sweethhheart16 小时前
【typora激活使用】mac操作方式
前端·数据库·macos
itslife16 小时前
vite 源码 - 创建服务
前端·javascript