Object.prototype.getB = function() {
// how to get the current value a
return a.b;
};
const a = {b: \'c\'};
a.getB();
As you can see, I want
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.
In your case, the function body should return this.b
. You can get the object itself with the this
keyword.
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. Extracting a method makes getB
a non-constructible method. All this ensures that getB
behaves very much like existing built-in methods (or methods provided by the host environment).
if(!Object.prototype.hasOwnProperty("getB")){
Object.defineProperty(Object.prototype, "getB", {
enumerable: false,
writable: true,
configurable: true,
value: {
getB(){
return this.b;
}
}.getB
});
}
If you can’t support methods, use this instead:
if(!Object.prototype.hasOwnProperty("getB")){
Object.defineProperty(Object.prototype, "getB", {
enumerable: false,
writable: true,
configurable: true,
value: function getB(){
return this.b;
}
});
}
Keep in mind that arrow functions cannot be used for this purpose since they don’t have their own this
context.
An alternative is to use a getter. Consider this:
const arr = [
"a",
"b",
"c",
];
console.log(arr.indexOfB); // 1
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
: property descriptors must not specify a value or be writable when a getter or setter has been specified
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", {
enumerable: false,
configurable: true,
get: {
indexOfB(){
return this.indexOf("b");
}
}.indexOfB
});
}
A setter can also be specified by adding a set
property to the descriptor:
if(!Array.prototype.hasOwnProperty("indexOfB")){
Object.defineProperty(Array.prototype, "indexOfB", {
enumerable: false,
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
});
}