在 JavaScript 中的 POJO 到底是什么?

发布于 2022-08-19 12:33:51 字数 3601 浏览 157 评论 0

关于 POJO 在 JavaScript 中是什么存在很多争论: StackOverflow 认为它是任何包含用户数据的类 ,但 Google 上的顶级 npm 模块 将 POJO 定义为 原型 Object.prototype

POJO 背后的直觉是 POJO 是一个只包含数据的对象,而不是方法或内部状态。 大多数 JavaScript 代码库都考虑使用花括号创建的对象 {} 成为 POJO。 然而更严格的代码库有时会 通过调用来 Object.create(null) 避免 从内置继承 Object

// If you create an object `obj` with `{}`, `obj` is an instance of
// the `Object` class, and so it has some built-in properties.
let obj = {};
obj.hasOwnProperty; // [Function]
obj.constructor === Object; // true

// On the other hand, `Object.create(null)` creates an object that
// doesn't inherit from **any** class.
obj = Object.create(null);
typeof obj; // 'object'
obj.hasOwnProperty; // undefined
obj.constructor; // undefined

obj.prop = 42;
obj.prop; // 42

POJOs 与 Maps

JavaScript Maps 是 POJO 存储数据的替代方案,因为它们没有任何继承自 Object 类。 但是,对象通常比映射更容易使用,因为并非所有 JavaScript 函数、框架和库都支持映射。
例如 JSON.stringify() 函数 不会序列化地图。

const map = new Map([['answer', 42]]);
JSON.stringify(map); // '{}'

检查对象是否为 POJO

检查一个对象是否是 POJO 可能有点棘手,这取决于您是否考虑使用创建的对象 Object.create(null) 成为 POJO。 最安全的方法是使用 Object.getPrototypeOf() 函数,并比较对象的原型。

function isPOJO(arg) {
  if (arg == null || typeof arg !== 'object') {
    return false;
  }
  const proto = Object.getPrototypeOf(arg);
  if (proto == null) {
    return true; // `Object.create(null)`
  }
  return proto === Object.prototype;
}

isPOJO({}); // true
isPOJO(Object.create(null)); // true
isPOJO(null); // false
isPOJO(new Number(42)); // false

比如下面是 Mongoose 的内部 isPOJO() 功能

exports.isPOJO = function isPOJO(arg) {
  if (arg == null || typeof arg !== 'object') {
    return false;
  }
  const proto = Object.getPrototypeOf(arg);
  // Prototype may be null if you used `Object.create(null)`
  // Checking `proto`'s constructor is safe because `getPrototypeOf()`
  // explicitly crosses the boundary from object data to object metadata
  return !proto || proto.constructor.name === 'Object';
};

Mongoose 检查 constructor.name 属性而不是检查是否 proto.constructor === Object 支持使用 Node.js vm 模块

const obj = require('vm').runInNewContext('({})');
// `obj` inherits from a different JavaScript context's `Object` class.
obj.constructor === Object; // false
obj.constructor.name; // 'Object'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

蒗幽

暂无简介

0 文章
0 评论
23 人气
更多

推荐作者

隔纱相望

文章 0 评论 0

昵称有卵用

文章 0 评论 0

梨涡

文章 0 评论 0

蓝咒

文章 0 评论 0

白芷

文章 0 评论 0

樱娆

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文