Home > Article > Web Front-end > Detailed explanation of call in javascript
This time I will bring you a detailed explanation of call in javascript, What are the precautions when using call in javascript, the following is a practical case, let’s take a look one time.
First of all, you must first understand that the function itself will have some properties of its own, such as:
length: the number of formal parameters;
name: Function name;
prototype: the prototype of the class, the methods defined on the prototype are all public methods of the current instance of this class;
proto: treat the function as an ordinary object, pointing to the prototype of the Function class
Function is the most complex and important knowledge in the entire JavaScript. For a function, there will be multiple roles:
function Fn() { var num = 500; this.x = 100; } Fn.prototype.getX = function () { console.log(this.x); } Fn.aaa = 1000;var f = new Fn; f.num // undefinedf.aaa // undefined12345678910111213 var res = Fn(); // res是undefined Fn中的this是window
Role 1: Ordinary function. For Fn, it itself is an ordinary Function, when executed, will form a private scope, and then carry out formal parameter assignment, pre-parsing, code execution, and memory destruction after execution is completed;
Role 2: Class, it has its own instance, f is Fn An instance generated as a class also has an attribute called prototype that is its own prototype. Its instances can point to its own prototype;
Role 3: Ordinary objects, Fn and var obj = {} Like obj, it is an ordinary object (all functions are instances of Function). As an object, it can have some private properties of its own, and Function.prototype can also be found through proto;
The above three types of functions Role, maybe most students have no doubts about role one and role two, but they may have a little doubt about role three, so draw a picture to understand:
Function as a normal object.png
call in-depth
var ary = [12, 23, 34]; ary.slice();
The execution process of the above two lines of simple code is: ary This example finds Array through the search mechanism of the prototype chain The slice method on .prototype allows the found slice method to be executed, and the ary array is intercepted during the execution of the slice method.
Note: Before the slice method is executed, there is a process of searching on the prototype (if it is not found in the current instance, it will be searched according to the prototype chain).
After knowing that there will be a search process for calling a method on an object, let’s look at:
var obj = {name:’iceman’}; function fn() { console.log(this); console.log(this.name); } fn(); // this –> window // obj.fn(); // Uncaught TypeError: obj.fn is not a function fn.call(obj);
The function of the call method: first search for the call method, and finally in the Function prototype through the prototype chain Find the call method, and then let the call method execute. When executing the call method, let this in the fn method become the first parameter value obj, and finally execute the fn function.
2.2. Principle of call method
Simulate the built-in call method in Function, write a myCall method, and explore the execution principle of the call method
function sum(){ console.log(this); }function fn(){ console.log(this); }var obj = {name:'iceman'};Function.prototype.myCall = function (context) { // myCall方法中的this就是当前我要操作和改变其this关键字的那个函数名 // 1、让fn中的this关键字变为context的值->obj // 让this这个函数中的"this关键字"变为context // eval(this.toString().replace("this","obj")); // 2、让fn方法在执行 // this();};1234567891011121314151617
fn.myCall( obj);//The original this in myCall method is fn
sum.myCall(obj);//The original this in myCall method is sum
When fn.myCall(obj); this line of code is executed , according to the search rules for this, if there is "." in front of the myCall method, then this in myCall is fn. To execute the myCall method, in the first step, this in the method body will be replaced with the incoming object, and the original this will be executed. Note: The original this is executed (I understood this for a long time when I was learning this). In this article In this example, fn is executed.
Are you a little confused after reading the above paragraph? Haha, it’s okay. Let’s look at the example below to understand it.
Classic example of call method
function fn1() { console.log(1); }function fn2() { console.log(2); }123456
Output one
fn1.call(fn2); // 1
First, fn1 finds the call method on Function.prototype through the prototype chain search mechanism, and lets the call method execute. At this time This in the call method is the fn1 to be operated. During the execution of the call method code, first let the "this keyword" in fn1 change to fn2, and then let the fn1 method execute.
Note: When executing the call method, this in fn1 will indeed change to fn2, but the content output in the method body of fn1 does not involve any content related to this. So it’s still output 1.
Output two
fn1.call.call(fn2); // 2
First fn1 finds the call method on Function.prototype through the prototype chain, and then lets the call method find the call on the Function prototype through the prototype (because The value of call itself is also a function, so you can also use Function.prototype), and then let the method execute when call is found for the second time. This in the method is fn1.call. First, let this in this method change to fn2. Then let fn1.call execute.
This example is a bit convoluted, but let’s understand it step by step. At the beginning, the this in the last call of the line of code fn1.call.call(fn2) is fn1.call. Based on the previous understanding, we can know that the principle of fn1.call is roughly:
Function.prototype.call = function (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是fn1};1234567
Write the above code in another form:
Function.prototype.call = test1;function test1 (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是fn1};12345678
We know that the two forms of writing have the same effect. Then you can write fn1.call.call(fn2) as test1.call(fn2) at this time, and this in the call is test1:
Function.prototype.call = function (context) { // 改变fn中的this关键字 // eval(....); // 让fn方法执行 this(); // 此时的this就是test1};1234567
Note: At this time, this in the call is test1.
Then replace this in call with fn2, then the test1 method becomes:
Function.prototype.call = function (context) { // 省略其他代码 fn2(); };12345
所以最后是fn2执行,所以最后输出2。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
The above is the detailed content of Detailed explanation of call in javascript. For more information, please follow other related articles on the PHP Chinese website!