闭包、定时器

2016-10-22  本文已影响0人  饥人谷__小圆

本教程版权归小圆和饥人谷所有,转载须说明来源

问题

代码题

var fnArr = []; 
for (var i = 0; i < 10; i ++) { 
    fnArr[i] = function(){ 
        return i; 
    }; 
} 
console.log( fnArr[3]() );    //输出10

方法一:

var fnArr = []; 
for (var i = 0; i < 10; i ++) {
    (function (n) {
      fnArr[i] = function(){ 
        return n; 
      };
    })(i);
} 
console.log( fnArr[3]() );    //3

方法二:

var fnArr = []; 
for (var i = 0; i < 10; i ++) {
    (function () {
      var s = i;
      fnArr[i] = function(){ 
        return s; 
      };
    })();
} 
console.log( fnArr[3]() );    //3
var Car = //todo;
Car.setSpeed(30);
Car.getSpeed(); //30
Car.accelerate();
Car.getSpeed(); //40;
Car.decelerate();
Car.decelerate();
Car.getSpeed(); //20
Car.getStatus(); // 'running';
Car.decelerate(); 
Car.decelerate();
Car.getStatus(); //'stop';
//Car.speed; //error

回答:

function speedSetting() {
    var speed;
    function setSpeed(s) {
      speed = s;
    }
    function getSpeed() {
      console.log(speed);
    }
    function accelerate() {
      speed += 10;
    }
    function decelerate() {
      speed -= 10;
    }
    function getStatus() {
      if (speed > 10) {
        status = 'running';
      } else {
        status = 'stop';
      }
      console.log(status);
    }
    return {
         setSpeed: setSpeed,
         getSpeed: getSpeed,
         accelerate: accelerate,
         decelerate: decelerate,
         getStatus: getStatus
    };
}

 var Car = speedSetting();
Car.setSpeed(30);
Car.getSpeed(); //30
Car.accelerate();
Car.getSpeed(); //40;
Car.decelerate();
Car.decelerate();
Car.getSpeed(); //20
Car.getStatus(); // 'running';
Car.decelerate(); 
Car.decelerate();
Car.getStatus(); //'stop';
//Car.speed; //error
var i = 0;
function simulateIntv() {
  setTimeout(function(){
     console.log(i++);
    simulatorIntv();
  },1000);
}
simulateIntv();
//虽然simulateIntv()能够模仿setInterval的计时效果,但时间间隔要比setInterval的长。
function getMini() {
  var i = 0;
  var start = Date.now();
  var clock = setTimeout(function() {
    i++;
    if (i === 1000) {
      clearTimeout(clock);
      var end = Date.now();
      console.log((end - start)/i);
    }
    clock = setTimeout(arguments.callee,0);
  },0);
}
getMini();    //4.027
var a = 1;
setTimeout(function(){ 
    a = 2; 
    console.log(a);
}, 0);
var a ;
console.log(a);
a = 3;
console.log(a);

输出:

1
3
2

原因:由于setTimeout的延迟时间为0,所以这段代码被延迟到其他代码执行完毕后执行,所以执行顺序为:

var a ;    //变量提升
var a = 1;
console.log(a);    //1
a = 3;
console.log(a);    //3
setTimeout(function(){ 
    a = 2; 
    console.log(a);    //2
}, 0);
var flag = true;
setTimeout(function(){ 
    flag = false;
},0)
while(flag){};
console.log(flag);

输出:没有输出
原因:由于setTimeout被放到执行顺序的最后,所以在当前所有代码执行完后才会执行flag = false;在这之前flag = true,当执行到while时,代码为空,执行陷入死循环,即while的代码一直处在未执行完毕的状态,所以后面的console.log(flag)setTimeout都无法执行,最后没有输出。

for(var i=0;i<5;i++){ 
    setTimeout(function(){ 
        console.log('delayer:' + i ); 
}, 0); 
    console.log(i);
}

输出:

0 1 2 3 4 "delayer:5" "delayer:5" "delayer:5" "delayer:5" "delayer:5"

回答:

for(var i=0;i<5;i++){ 
  (function (n) {
     setTimeout(function(){ 
         console.log('delayer:' + n ); 
     }, 0); 
  })(i);
}

输出:

"delayer:0" "delayer:1" "delayer:2" "delayer:3" "delayer:4"
上一篇 下一篇

猜你喜欢

热点阅读