问题
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 to make a function to all Object value. And I need to get the object value in this function then do something.
回答1:
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.
Methods
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 and make the property writable, configurable and non-enumerable. Extracting the 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 create their own this
context.
Getters / Setters
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. Next, value
needs to 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
});
}
来源:https://stackoverflow.com/questions/46491209/how-to-get-object-itself-in-custom-object-prototype-xxx-function