First, preface
Let's start by predicting the results of the following four function calls!
var test = function () { console.log ('helloworld')
Return ' Fsjohnhuang '}
// ② // ③ // ④
Announcement: ①, ③ and ④. The console displays Hello World and returns Fsjohnhuang. ②. Returns undefined and does not call the test function;
What the hell is going on here? Here are the one by one lanes.
Second, from the commonly used call function
Let's just say it through the code.
var test2 = function () {Console.log ( this ) " fsjohnhuang '
Test2.call is actually called Function.prototype.call (Thisarg [, Arg1 [, arg2, ...]) , and its role I think we all know, but its internal working principle is how? At this point we can refer to the ECMAScript5.1 language specification. The following is the pseudo-code of the reference specification (the specific implementations of each browser are different)
Function.prototype.call =function (Thisarg, arg1, arg2, ...) { /***Note: This points to the object or function that called call ***/
//1. Call the internal iscallable (this) to check if it is callable, and return false to throw TypeError if(! [[Iscallable]] ( This))Throw NewTypeError ()//2. Create an empty list//3. Save the Arg1 and the subsequent entry to the arglist varArgList = [].slice.call (arguments,1) //4. Call the internal [[call]] function return[[Call]] ( This, Thisarg, argList)}
Now we can analyze ①test.call () and use it as a basis to understand the following. Its internal implementation of the pseudo-code is as follows:
Test.call = function (thisarg, arg1, arg2, ...) { ifthrownew TypeError () var1) return [[Call]] (test, Thisarg, argList)}
Here we will analyze ② Function.prototype.call (test) , pseudo-code as follows:
Function.prototype.call = function (test, arg1, arg2, ...) { /* * * * * Function.prototype is a function Empty () {} * ** * * * thrownew TypeError () var1) It's actually called the empty function, which returns undefined as a matter of course return [[Call]] (Function.prototype, Test, ArgList)}
Thirdly, what is the internal Function.prototype.call.call?
With the foundation above, Function.prototype.call.call is not difficult to understand. Is the thisarg of the last Call function as the this value of Function.prototype.call! The pseudo code is as follows:
//test as Thisarg incomingFunction.prototype.call.call =function (test, arg1, arg2,...) { if([[Iscallable]] (Function.prototype.call))Throw NewTypeError ()varArgList = [].slice.call (arguments,1) return[[Call]] (Function.prototype.call, Test, argList)}//test as the This value of the function//Note: The value of the entry Thisarg is the Function.prototype.call.call of the entry for the parameter arg1Function.prototype.call =function (Thisarg, arg1, arg2,...) { if([[iscallable]] (test))Throw NewTypeError ()varArgList = [].slice.call (arguments,1) return[[Call]] (test, Thisarg, argList)}
Four, the Devil of the--function.prototype.call.call (Function.prototype.call, test)
Look at the pseudo-code to understand it!
//test as arg1 incomingFunction.prototype.call.call =function (Function.prototype.call, test) {if([[Iscallable]] (Function.prototype.call))Throw NewTypeError ()varArgList = [].slice.call (arguments,1) return[[Call]] (Function.prototype.call, Function.prototype.call, ArgList)} Function.prototype.call=function (test) {if([[Iscallable]] (Function.prototype.call))Throw NewTypeError ()varArgList = [].slice.call (arguments,1) return[[Call]] (Function.prototype.call, Test, ArgList)} Function.prototype.call=function (thisarg) {if([[iscallable]] (test))Throw NewTypeError ()varArgList = [].slice.call (arguments,1) return[[Call]] (test, Thisarg, argList)}
Isn't this a step more than the third verse? Is there a must?
Five, new play--Traversal execution function array
Array.prototype.resolve = function () { this. ForEach (Function.prototype.call, Function.prototype.call)}var cbs = [function () {Console.log (1)}, function () {Console.log ( 2// console output // 1// 2
What is this for? Let's take a look at the internal implementation of Array.prototype.forEach (FN, Thisarg) , which is the following pseudo-code:
Array.prototype.forEach = function (FN, thisarg) { var item for (var 0this. length; i < Len; + +i) {This[i ]this) }}
The pseudo-code of the Function.prototype.call.call (Function.prototype.call, item, I, this) will be written on your own.
Vi. Summary
In the project about the use of Function.prototype.call.call is really rare, and performance is not high, this article only for the purpose of learning, only want to get a deeper understanding of the internal principles of Function.prototype.call.
Respect the original, reproduced please specify in: http://www.cnblogs.com/fsjohnhuang/p/4160942.html ^_^ Fat Boy John
Vii. Reference
Calls a set of function methods in an array of javascript
Https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach
Annotated ECMAScript 5.1
JS Magic Hall: Meet Function.prototype.call again