According to the Function. The prototype. The call () – the definition of JavaScript | MDN
The call() method calls a function with a specified value of this and one or more arguments given separately.
preface
This article only discusses changing the reference to this within normal functions, and to simplify the problem does not distinguish between strict mode /null/undefined
The default target type is object. No other types are discussed
Several ways to change the function this
Function assigns a value directly to the target object
Function.prototype.call2 = function (context, ... args) {
let uniqueKey = Symbol("Globally unique reference");
context[uniqueKey] = this;
letresult = context[uniqueKey](... args);delete context[uniqueKey];
return result;
};
Copy the code
Disadvantages: If the object is frozen or is a Proxy, the function assignment fails and the original object structure is destroyed
function test(){
return this.a+this.b
}
ob1 = {a:1.b:2}
Copy the code
Call example
1 / / examples
Object.seal(ob1)
test.call2(ob1)
Copy the code
2 / / examples
Object.freeze(ob1)
test.call2(ob1)
Copy the code
3 / / examples
ob1 = new Proxy(ob1, {
set(target, key, value){}}); test.call2(ob1)Copy the code
Will get the following error:
VM86:4 Uncaught TypeError: context[uniqueKey] is not a function
at Function.call2 (<anonymous>:4:34)
at <anonymous>:1:6
Copy the code
Change this with the prototype chain
Function.prototype.call3 = function (context, ... args) {
const obj = Object.create(context);
let uniqueKey = Symbol("Globally unique reference");
obj[uniqueKey] = this;
returncontext[uniqueKey](... args); };Copy the code
This approach solves the problem of the object being frozen/property intercepted, but the calling object is not the original object
If there is an operation on the prototype, the unexpected behavior occurs
conclusion
Function. The prototype. The call is native code
A complete function.prototype. call cannot be implemented in pure JS