• Blogs (9)
    • 📱 236 - 992 - 3846

      📧 jxjwilliam@gmail.com

    • Version: ‍🚀 1.1.0
  • How many ways to make setTimeout work properly?

    Blogs20152015-10-23


    How many ways to make setTimeout work properly?

    The setTimeout output is incorrectly, always 5.

    for(i=0; i<5; i++) {
    	setTimeout(function() {
    		console.log('wrong output: ', i);
    	}, 100); //5
    }

    The following is my 6 ways to make it display correctly:

    //1. function: copy value
    function fn(i) {
        return function() {
    	console.info(i);
        }
    }
    for(i=0; i<5; i++) {
    	setTimeout(fn(i), 100);
    }
    
    //2. bind: create new function, same as (1)
    //The bind() method creates a new function that, when called, has its this keyword set to the provided value, with a given sequence of arguments preceding any provided when the new function is called.
    for(i=0; i<5; i++) {
    	setTimeout(console.log.bind(console, i), 100);
    }
    
    //3. IIFE, pass value instead of reference
    for(i=0; i<5; i++) {
    	(function(i) {
    		setTimeout(function() {
    			console.log(i);
    		}, 100);
    	}(i));
    }
    
    //4. inside setTimeout, do the IIFE:
    for(i=0; i<5; i++) {
        	setTimeout((function(i) {
                return function() {
    		console.log(i);
                }
    	}(i)), 100);
    }
    
    //5. use call() to pass value instead of reference
    //The call() method calls a function with a given this value and arguments provided individually.
    for(i=0; i<5; i++) {
    	setTimeout(function() {
    		console.log(i);
    	}.call(i), 100);
    }
    
    //6. use apply() to pass value instead of reference
    //The apply() method calls a function with a given this value and arguments provided as an array (or an array-like object).
    for(i=0; i<5; i++) {
    	setTimeout(function() {
    		console.log(i);
    	}.apply(i), 100);
    }

    It is cool, oh? More solution?