The this,settimeout/setinterval,arguments of JS black Magic

Source: Internet
Author: User

Recently found JavaScript garden this JS black magic collection, but there are some things are not very thorough, so while looking at the document or do experiments, write some notes, conveniently placed on the blog. After watching you don ' t know JS talk about this and prototype part, perhaps again will write a little.

Function name is optional

Where anonymous functions are usually used, anonymous functions can also be named (ES3 start). Provides additional information/recursion for debugging purposes.

Foo (function Bar () {...});

But at this time bar can only be accessed in bar, not outside access (not defined). In the same way:

var function Bar () {    //  Works//  referenceerror

This is with

function Bar () {...}

The difference is that the latter is assigned window (or other global object), which is equivalent to

function () { ... }

The reference to the former is transferred foo (the first paragraph is not accessible elsewhere). Assigned to global object, of course, can be accessed. Because of the JS name resolution, the function name can be accessed within the function itself.

Worm: ie8-will leak this bar out to the outside =__=!!

Five kinds of bindings for this
  1. Use this directly in the global object, referring to the

    Console.log (this//  true
  2. In a function foo() function that is declared in form, it is also a global object (note that even function declarations are embedded in the method, which is discussed later)

    function foo () {    Console.log (this//  true};foo ();
  3. In the shape of the call, refers to the object of the call, the a.foo() point in front of the thing (note that the parentheses must appear in the form of a method call , otherwise called is not a method, is still a normal function, look at the text)

    var a =function() {    Console.log (this// true };a.foo ();
  4. In the constructor, it refers to the new object. Note that this cannot be this == b done directly, because the new constructed object itself is different before and after the constructor call, but if you delay it, you can see that this is pointing to the new object being returned. (Save with that instead of using this directly because the SetTimeout calls the function with the global object, read later)

    function foo () {    varthis;    SetTimeout (function//  true}varnew foo ();
  5. What do you mean, where to apply call bind play?

This binding for inline functions
var foo =function() {    function  Test () {        Console.log (  this = = = window);  // true     }    Test ();} Foo.method ();

If a function is declared in a method, this in this function becomes the global object, which is not the same as the outside. As a matter of fact, you can see what's going on:

var foo =function() {    function() {  //  test belongs To the Global object        console.log ( this = = window);  // true     }    Test ();} Foo.method ();

The main thing to understand is to use function test() {} this statement directly, wherever it is bound to the global object. To be placed locally, you must use function expression,var test = function test() {}

The general workaround are:

  1. Common use that

     var  foo = {}; Foo.method  = function   () { var  that = this  ;  var  test = function  Test () {//  store the outer this  console.log (that = = foo); //   

    To let the function inside can also use the outside of this. (Note that it is not a special name, can be used casually) is usually used in conjunction with closures, to transfer this. Note that the var test = function test () is the key, if you still use function test () , in fact, because Test is still tied to the global object, Just add a closure, and so test leaks to the global, you can directly in the global call this seems to be only the method of the test function ... 2333

  2. Binds the inline function on this

     var  foo = {}; Foo.method  = function   () { this . _test = function   () {Console.log (  /span>this  = = foo); //    ._ Test ();} Foo.method ();  

    But this way Foo takes extra + exposes a function that is not needed outside

  3. With Bind

    var foo =function() {    var test = (function  Test () {        Console.log ( this = = foo);  // true    }). Bind (this);    Test ()}foo.method ();
Delay binding for this
var bar =function() {    Console.log (this = = = bar);  // false    Console.log ( this = = = window);  // true }var foo = bar.baz;foo ();

fooThis again refers back to the object--global foo belongs to. So this is bound when the function is executed and not declared, which is the basis of Prototypal inheritance

functionfunction() {    Console.log (this = = b);  // B would be available if executed after B is declared! }; function  = foo.prototype; var New Bar (); B.method ();

In B.method () this refers to B (instance of bar), otherwise it should be an instance of Foo ... Oh that is implemation inheritance. Note that when the function executes , there is already a B, so the reference to B in Foo does not result in an error. JS in the function of the references are deferred to the execution of the search, the declaration is not checked.

This in the settimeout.
 function   Foo () { this . Value = 42;  this . Method = function   () { //  This refers to the global object  Console.log (this . Value); //   undefined  console.log (this  = = = window); //     }; SetTimeout ( this . Method, 500 new  Foo (); 

The settimeout is removed from the current context and the first argument is called with global object. In fact setTimeout(this.method, 500); , it's just that the brain complements the call this.method() , but the fact that it's uploaded is a function reference without bind , which can be understood as:

this. method;  // method belongs to the global objectSetTimeout (method, 500);

Simply put, just remember that a call to the code is actually seen in the form this.method() (note parentheses) to the point where the function executes before it points to the previous part. You can't take it for granted without seeing the parentheses.

If you want this to be an intuitive object, you can use the that+ closure to ensure that this is the value you want in the function passed in.

functionFoo () { This. Value = 42; varthat = This;  This. method =function() {        //This refers to the new instanceConsole.log (That.value);// theConsole.log (that = = = B);//true    }; SetTimeout ( This. method, 500);}varb =NewFoo ();

or by bind :

function Foo () {    this. Value =;      method = (function  method () {        Console.log (this//  42         Console.log (this//  true    }). bind (this);    SetTimeout (this. method,);} var New Foo ();
SetTimeout V.s. setinterval

SetInterval just call the function, no matter how the function executes, so if the called function is blocked, and the blocking time is greater than the call interval, then when the function is finished, there may be a large wave of functions that have not yet started executing, like this:

function foo () {    //  something that blocks for 1 second100);

Workaround is

function foo () {    //  something this blocks for 1 second    setTimeout (foo, +);} Foo ();

This waits until the function has finished executing, waiting for the interval, and then making the next call. Note that using settimeout+ to pass a function recursively is not StackOverflow , because the settimeout+ function simply makes the token to be called instead of actually being called. The passed in function will return immediately after execution (SetTimeout will not block, so there is no need to wait for him to return), will not be waiting on the stack, nature will not stackoverflow.

How to clear all timeout

setTimeoutis part of the DOM (and Dom 0), so it is not stated in the ECMAScript standard , but in the major browsers, SetTimeout's ID is actually the greater the later, so you can immediately settimeout a bit, Get the current maximum ID, and then clear it individually

// clear "All" timeouts var biggesttimeoutid = window.settimeout (function() {}, 1), I;  for (i = 1; I <= biggesttimeoutid; i++) {    cleartimeout (i);}

But because the standard does not say , so this method in the future is not necessarily reliable. HTML5 to SetTimeout, but the current specification for this returned ID is "a user-agent-defined integer, which is greater than zero," would identify the Timeou T to is set by the the the list of active timers. " That is to say, as long as the only positive integer can be, as to how the change is user-agent-defined, still not reliable AH poof

Arguments is not an array
    • So it can't be used push , popslice
    • can be used for-in
    • Converting to arrays

      Array.prototype.slice.call (arguments);

      But this approach 1. Slow 2. The interpreter cannot be optimized so don't use it when it's not necessary.

    • ES5 Strict mode arguments cannot be used [] to access or modify
Arguments.callee

optimize the killer and try not to use it .

arguments.calleeIt is usually used to reference the function itself, but it apply call can be replaced entirely with the function name unless it is used. arguments.callee.caller(same Function.caller ) is commonly used to reference functions that call this function, but this usage obviously destroys encapsulation (the function's behavior depends on the invoked context). Using arguments.callee or Function.caller after the interpreter is difficult to determine the behavior of the function, resulting in no inline optimization.

The use of ES5 Strict mode arguments.callee will be an error.

The this,settimeout/setinterval,arguments of JS black Magic

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.