能否手动打破JS中预定义的Numbers、Strings、Boolean、Arrays原型链或重新赋值
Can we break the pre-defined prototype chain of Numbers, Strings, Boolean, Arrays in JS Manually or Reassign Values
时,我们新建一个number类型的变量(比如num1),它的__proto__
指向Number Object
。它的 __proto__
将再次指向 Object Core
,它的 __proto__
指向 null
,从而结束原型链。
我想做的是通过尝试将 __proto__
link 从 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__);
输出:
修改基本对象的 built-in 原型,或 built-in 原型链,在一般情况下是一个非常糟糕的主意。我强烈建议不要这样做。
Number.__proto__
是 Number
函数的原型, 不是 Number
对象的原型(即 Number.prototype
).
此外,JavaScript 同时具有数字基元和数字对象。大多数时候,您正在处理一个数字基元。当您在数字原语 (n = 42
) 上使用属性(包括方法)时,例如 toString
,JavaScript 引擎从 Number.prototype
获取这些属性,即使 n
是原语。
你可以改变Number.prototype
的原型。例如,您可以将其设置为 null
,以便 Number
对象不再继承自 Number.prototype
以外的任何对象(用 Object.prototype
打破 link),意思是 属性 对数字基元的查找不再从 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)
returns 原始数字 n
的 Number
对象。我在那里使用它是因为 instanceof
总是 false
对于基元 [n instanceof Number
是 false
,例如。为了检查继承,我们临时需要一个对象。)
如您所见,Number
对象和 Object
之间的 link 已经断开。
同样,在一般情况下这是一个非常糟糕的主意,因为它往往会破坏事物。仅仅因为我们可以这样做并不意味着我们应该.
However, I know I can add certain item in the middle of chain (like in Number-Object) by following code:
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 anywhere above. It's deprecated and should not be used in new code, use Object.getPrototypeOf
and (if absolutely necessary) Object.setPrototypeOf
。对于不从 Object.prototype
继承的任何对象,它也会失败,因为那是定义 __proto__
访问器 属性 的地方。
时,我们新建一个number类型的变量(比如num1),它的__proto__
指向Number Object
。它的 __proto__
将再次指向 Object Core
,它的 __proto__
指向 null
,从而结束原型链。
我想做的是通过尝试将 __proto__
link 从 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__);
输出:
修改基本对象的 built-in 原型,或 built-in 原型链,在一般情况下是一个非常糟糕的主意。我强烈建议不要这样做。
Number.__proto__
是 Number
函数的原型, 不是 Number
对象的原型(即 Number.prototype
).
此外,JavaScript 同时具有数字基元和数字对象。大多数时候,您正在处理一个数字基元。当您在数字原语 (n = 42
) 上使用属性(包括方法)时,例如 toString
,JavaScript 引擎从 Number.prototype
获取这些属性,即使 n
是原语。
你可以改变Number.prototype
的原型。例如,您可以将其设置为 null
,以便 Number
对象不再继承自 Number.prototype
以外的任何对象(用 Object.prototype
打破 link),意思是 属性 对数字基元的查找不再从 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)
returns 原始数字 n
的 Number
对象。我在那里使用它是因为 instanceof
总是 false
对于基元 [n instanceof Number
是 false
,例如。为了检查继承,我们临时需要一个对象。)
如您所见,Number
对象和 Object
之间的 link 已经断开。
同样,在一般情况下这是一个非常糟糕的主意,因为它往往会破坏事物。仅仅因为我们可以这样做并不意味着我们应该.
However, I know I can add certain item in the middle of chain (like in Number-Object) by following code:
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 anywhere above. It's deprecated and should not be used in new code, use Object.getPrototypeOf
and (if absolutely necessary) Object.setPrototypeOf
。对于不从 Object.prototype
继承的任何对象,它也会失败,因为那是定义 __proto__
访问器 属性 的地方。