我们可以手动断开JS中预定义的数字、字符串、布尔值、数组的原型链,或者重新赋值吗

Can we break the pre-defined prototype chain of Numbers, Strings, Boolean, Arrays in JS Manually or Reassign Values(我们可以手动断开JS中预定义的数字、字符串、布尔值、数组的原型链,或者重新赋值吗)
本文介绍了我们可以手动断开JS中预定义的数字、字符串、布尔值、数组的原型链,或者重新赋值吗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我们创建一个Number类型的新变量(比如Num1)时,它的__proto__指向Number Object。它的__proto__将再次指向Object Core,其__proto__指向null,从而结束原型链。 我尝试做的是通过尝试将__proto__链接从Number Object更改为某个字符串来覆盖中间的这个链。我无法中断链,因为在我的赋值之后,它仍然指向Object Core结构。

断开此原型链是我做错了什么,还是无法在浏览器中断开预定义的原型链!

Number.__proto__ = "abc"; 
let num4 = 8;
console.log(num4.__proto__);//returns Number Object
console.log(num4.__proto__.__proto__)//should return string "abc"

输出:

不过,我知道我可以通过以下代码在链的中间添加某些项目(如Number-Object):

Number.prototype.alpha = "def";
let num5 = 99; 
console.log(num5.__proto__);

输出:

推荐答案

修改基本对象的内置原型或内置原型链通常是非常糟糕的想法。我强烈建议您不要这么做。

Number.__proto__Number函数的原型,不是Number对象(即Number.prototype)的原型。

此外,JavaScript同时具有Number基元和Number对象。大多数情况下,您要处理的是一个原始的数字。当您在Number基元(n = 42)(如LIKEtoString)上使用属性(包括方法)时,即使n是基元,JavaScript引擎也会从Number.prototype获取这些属性。

可以更改Number.prototype的原型。例如,您可以将其设置为null,以便Number对象不再继承Number.prototype以外的任何对象(用Object.prototype断开链接),这意味着对数字原语的属性查找不再从Object.prototype中找到属性和方法:

const n = 8;
console.log(typeof n.hasOwnProperty);           // function
console.log(Object(n) instanceof Number);       // true
console.log(Object(n) instanceof Object);       // true
Object.setPrototypeOf(Number.prototype, null);
console.log(typeof n.hasOwnProperty);           // undefined
console.log(Object(n) instanceof Number);       // true
console.log(Object(n) instanceof Object);       // false

(Object(n)返回数字原语nNumber对象。我在那里使用它是因为instanceof对于原语总是false[例如n instanceof Numberisfalse]。若要检查继承,我们临时需要一个对象。)

如您所见,Number对象和Object之间的链接已断开。

再说一次,这在一般情况下是一个非常糟糕的想法,因为它往往会打碎东西。仅仅因为我们可以做并不意味着我们应该

不过,我知道我可以通过以下代码在链的中间添加某些项目(如Number-Object):

Number.prototype.alpha = "def";
let num5 = 99; 
console.log(num5.__proto__);

这只是向Number.prototype添加属性,而不是向原型链中插入某些内容。但是也可以插入到原型链中,因为我们可以更改Number.prototype

的原型
function Custom() {
}
// Change `Custom.prototype` to an object whose prototype
// is the prototype of `Number.prototype` (which will be
// `Object.prototype` in an unsullied environment).
// (`Object.create` creates an object setting its prototype
// to the given object.)
Object.defineProperty(Custom, "prototype", {
    value: Object.create(Object.getPrototypeOf(Number.prototype)),
    writable: true,
});
Object.defineProperty(Custom.prototype, "constructor", {
    value: Custom,
    writable: true,
    configurable: true,
});
Object.defineProperty(Custom.prototype, "example", {
    value() {
        return "hi there";
    },
    writable: true,
    configurable: true,
});
Object.setPrototypeOf(Number.prototype, Custom.prototype);

const n = 8;
console.log(n.example());                 // "hi there"
console.log(Object(n) instanceof Custom); // true

我在那里使用了构造函数,这样我们就可以方便地使用instanceof检查继承,但是您可以在没有构造函数的情况下插入原型。下面是不带一个相同代码:

const custom = Object.create(Object.getPrototypeOf(Number.prototype));
Object.defineProperty(custom, "example", {
    value() {
        return "hi there";
    },
    writable: true,
    configurable: true,
});
Object.setPrototypeOf(Number.prototype, custom);

const n = 8;
console.log(n.example()); // "hi there"


注意1:最好避免更改现有对象的原型(例如,使用Object.setPrototypeOf)。JavaScript引擎基于这样的假设进行优化(通常是正确的),即对象的原型在创建之后不会更改。更改它会打破这一假设,从而从对象中删除这些优化。

注意2:您会注意到我没有在上面的任何地方使用__proto__ accessor property。它已弃用,不应在新代码中使用,请改用Object.getPrototypeOf和(如果绝对必要)Object.setPrototypeOf。对于不是从Object.prototype继承任何对象,它也会失败,因为__proto__访问器属性就是在这里定义的。

这篇关于我们可以手动断开JS中预定义的数字、字符串、布尔值、数组的原型链,或者重新赋值吗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)