问题
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