如何在自定义 Object.prototype.xxx 函数中获取对象本身? [英] How to get object itself in custom Object.prototype.xxx function?
问题描述
Object.prototype.getB = function() {
// how to get the current value a
return a.b;
};
const a = {b: 'c'};
a.getB();
如您所见,我想为所有 Object 值制作一个函数.我需要在这个函数中获取对象值然后做一些事情.
As you can see, I want to make a function to all Object value. And I need to get the object value in this function then do something.
推荐答案
Monkey Patching
你想做的是猴子补丁 — 你改变一个内置原型.有很多错误的方法可以做到,但我将演示一种目前最正确的方法.
Monkey Patching
What you want to do is called monkey patching — you mutate a built-in prototype. There are many wrong ways to do it, but I’ll demonstrate a way that is currently the most correct way.
在您的情况下,函数体应返回 this.b
.您可以使用 this
关键字获取对象本身.
In your case, the function body should return this.b
. You can get the object itself with the this
keyword.
如果你真的想打猴子补丁,事先检查函数是否存在以确保向前兼容并使属性可写、可配置和不可枚举(最后一个是默认值)使用 defineProperty
时).提取 方法 使 getB
一个不可构造的函数.所有这些确保 getB
的行为与现有的内置方法(或宿主环境提供的方法)非常相似.
If you really want to monkey-patch, check for the function’s existence beforehand to ensure forward-compatibility and make the property writable, configurable, and non-enumerable (the last of which is the default when using defineProperty
). Extracting a method makes getB
a non-constructible function. All this ensures that getB
behaves very much like existing built-in methods (or methods provided by the host environment).
if(!Object.hasOwn(Object.prototype, "getB")){
Object.defineProperty(Object.prototype, "getB", {
writable: true,
configurable: true,
value: {
getB(){
return this.b;
}
}.getB
});
}
Object.hasOwn
是一种相当新的方法,但在旧环境中,它可以简单地替换为 Object.prototype.hasOwnProperty.call
或其变体.如果您不能支持方法,请改用它:
Object.hasOwn
is quite a new method, but in older environments it can simply be replaced by Object.prototype.hasOwnProperty.call
or a variant thereof. If you can’t support methods, use this instead:
if(!Object.prototype.hasOwnProperty("getB")){
Object.defineProperty(Object.prototype, "getB", {
writable: true,
configurable: true,
value: function getB(){
return this.b;
}
});
}
请记住,箭头函数 不能用于此目的,因为它们没有自己的 this
绑定.
Keep in mind that arrow functions cannot be used for this purpose since they don’t have their own this
binding.
另一种方法是使用吸气剂.考虑一下:
An alternative is to use a getter. Consider this:
const arr = [
"a",
"b",
"c",
];
console.log(arr.indexOfB); // 1
Array
原型上的 indexOfB
getter 是什么样的?我们不能用上面的方法用get
代替value
,否则我们会得到:
How would an indexOfB
getter on the Array
prototype look like? We can’t use the above approach and replace value
by get
, or else we’ll get:
TypeError
:当指定了 getter 或 setter 时,属性描述符不得指定值或可写
TypeError
: property descriptors must not specify a value or be writable when a getter or setter has been specified
属性writable
需要从描述符中完全删除.现在 value
可以替换为 get
:
The property writable
needs to be removed entirely from the descriptor. Now value
can be replaced by get
:
if(!Array.prototype.hasOwnProperty("indexOfB")){
Object.defineProperty(Array.prototype, "indexOfB", {
configurable: true,
get: {
indexOfB(){
return this.indexOf("b");
}
}.indexOfB
});
}
还可以通过向描述符添加 set
属性来指定 setter:
A setter can also be specified by adding a set
property to the descriptor:
if(!Array.prototype.hasOwnProperty("indexOfB")){
Object.defineProperty(Array.prototype, "indexOfB", {
configurable: true,
get: {
indexOfB(){
return this.indexOf("b");
}
}.indexOfB,
set: {
indexOfB(newValue){
// `newValue` is the assigned value.
// Use `this` for the current Array instance.
// No `return` necessary.
}
}.indexOfB
});
}
这篇关于如何在自定义 Object.prototype.xxx 函数中获取对象本身?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!