JS Magic Hall: Meet Function.prototype.call again

Source: Internet
Author: User

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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.