问题
I have come across an interesting behavior when playing around and trying to override Function prototype.
Let's assume we have overriden toString() like this:
const funcToString = Function.prototype.toString;
Function.prototype.toString = function() {
console.log("lol");
return funcToString.call(this);
}
Now, lets take this into action and see what happens:
(function foo(){}).toString(); // TypeError
TypeError: Function.prototype.toString requires that 'this' be a Function
By doing some reading, I've learned that this has something to do with how internally Function wraps it in a Proxy - and it being indistinguishable from it's target, results in a TypeError.
But now, we can try doing this:
function boo(){};
boo.toString(); // prints "lol", as we wanted
To add to all this, I've only observed this behavior in browser runtimes. In Node.js, everything goes well in both scenarios.
EDIT: Confirmed to work in REPL without any errors whatsoever.
Personally I fail to understand what the difference is / what exactly happens. Would be grateful if someone could shine some light on this.
回答1:
This is a problem of a missing semicolon:
Function.prototype.toString = function() {
…
}; /*
^ */
(function foo(){}).toString();
Otherwise it is interpreted as
Function.prototype.toString = function(){…}(function foo(){}).toString();
which calls the function expression that is supposed to override toString like an IIFE
… (function(){…}(function foo(){})) …
…in the global context, not on a function.
来源:https://stackoverflow.com/questions/48659417/overriding-function-type-prototypes