Object 您所在的位置:网站首页 js获取原型的方法有哪些 Object

Object

2024-07-16 16:04| 来源: 网络整理| 查看: 265

几乎所有的 JavaScript 对象最终都继承自 Object.prototype(参见继承和原型链)。然而,你可以使用 Object.create(null) 或定义了 __proto__: null 的对象字面量语法(注意:对象字面量中的 __proto__ 键不同于已弃用的 Object.prototype.__proto__ 属性)来创建 null 原型对象。你还可以通过调用 Object.setPrototypeOf(obj, null) 将现有对象的原型更改为 null。

jsconst obj = Object.create(null); const obj2 = { __proto__: null };

null 原型对象可能会有一些预期外的行为表现,因为它不会从 Object.prototype 继承任何对象方法。这在调试时尤其需要注意,因为常见的对象属性转换/检测实用方法可能会产生错误或丢失信息(特别是在使用了忽略错误的静默错误捕获机制的情况下)。

例如,Object.prototype.toString() 方法的缺失通常会使得调试变得困难:

jsconst normalObj = {}; // 创建一个普通对象 const nullProtoObj = Object.create(null); // 创建一个 "null" 原型对象 console.log(`normalObj 是:${normalObj}`); // 显示 "normalObj 是:[object Object]" console.log(`nullProtoObj 是:${nullProtoObj}`); // 抛出错误:Cannot convert object to primitive value alert(normalObj); // 显示 [object Object] alert(nullProtoObj); // 抛出错误:Cannot convert object to primitive value

其他方法也会失败。

jsnormalObj.valueOf(); // 显示 {} nullProtoObj.valueOf(); // 抛出错误:nullProtoObj.valueOf is not a function normalObj.hasOwnProperty("p"); // 显示 "true" nullProtoObj.hasOwnProperty("p"); // 抛出错误:nullProtoObj.hasOwnProperty is not a function normalObj.constructor; // 显示 "Object() { [native code] }" nullProtoObj.constructor; // 显示 "undefined"

我们可以通过为 null 原型对象分配属性的方式将 toString 方法添加回去:

jsnullProtoObj.toString = Object.prototype.toString; // 由于新对象缺少 `toString` 方法,因此需要将原始的通用 `toString` 方法添加回来。 console.log(nullProtoObj.toString()); // 显示 "[object Object]" console.log(`nullProtoObj 是:${nullProtoObj}`); // 显示 "nullProtoObj 是:[object Object]"

普通对象的 toString() 方法是在对象的原型上的,而与普通对象不同的是,这里的 toString() 方法是 nullProtoObj 的自有属性。这是因为 nullProtoObj 没有原型(即为 null)。

在实践中,null 原型对象通常被用作 map 的简单替代品。由于存在 Object.prototype 属性,会导致一些错误:

jsconst ages = { alice: 18, bob: 27 }; function hasPerson(name) { return name in ages; } function getAge(name) { return ages[name]; } hasPerson("hasOwnProperty"); // true getAge("toString"); // [Function: toString]

使用一个 null 原型对象可以消除这种风险,同时不会令 hasPerson 和 getAge 函数变得复杂:

jsconst ages = Object.create(null, { alice: { value: 18, enumerable: true }, bob: { value: 27, enumerable: true }, }); hasPerson("hasOwnProperty"); // false getAge("toString"); // undefined

在这种情况下,添加任何方法都应该慎重,因为它们可能会与存储为数据的其他键值对混淆。

让你的对象不继承自 Object.prototype 还可以防止原型污染攻击。如果恶意脚本向 Object.prototype 添加一个属性,程序中的每个对象上都可访问它,除了那些原型为 null 的对象。

jsconst user = {}; // 恶意脚本: Object.prototype.authenticated = true; // 意外允许未经身份验证的用户通过 if (user.authenticated) { // 访问机密数据 }

JavaScript 还具有内置的 API,用于生成 null 原型对象,特别是那些将对象用作临时键值对集合的 API。例如:

Object.groupBy() 方法的返回值 RegExp.prototype.exec() 方法返回结果中的 groups 和 indices.groups 属性 Array.prototype[@@unscopables] 属性(所有 @@unscopables 对象原型都应该为 null) importa 对象 通过 import * as ns from "module" 或 import() 获取的模块命名空间对象

“null 原型对象”这个术语通常也包括其原型链中没有 Object.prototype 的任何对象。当使用类时,可以通过 extends null 来创建这样的对象。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有