闭包??

2017-08-31  本文已影响0人  王翔爱摇滚乐爱电影爱心理学爱哲

什么闭包,闭包有什么用?
http://js.jirengu.com/pogadikofa/1/
闭包是在某个作用域内定义的函数,它可以访问这个作用域内的所有变量。闭包作用域链通常包括三个部分:

函数本身作用域。
闭包定义时的作用域。
全局作用域。
闭包常见用途:

创建特权方法用于访问控制
事件处理程序及回调

1: 下面的代码输出多少?修改代码让 fnArri 输出 i。

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(i){
        fnArr[i] = function(){
            return i;
        }
    })(i);
}
console.log( fnArr[3]() );  //3
//方法二
var fnArr = [];
for (var i = 0; i < 10; i ++) {
    fnArr[i] =  (function(i){ //IIFE & 闭包
        return function(){
            return i;
        }
    })(i);
}
console.log( fnArr[3]() );  //3
//方法三 ES6
var fnArr = [];
for (let i = 0; i < 10; i ++) { //使用ES6: let
    fnArr[i] =  function(){
        return i;
    };
}
console.log( fnArr[3]() );

2、封装一个汽车对象,可以通过如下方式获取汽车状态

var Car = (function(){
   var speed = 0;
   function setSpeed(s){
       speed = s
   }
   ...
   return {
      setSpeed: setSpeed,
      ...
   }
})()
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 Car = (function () {
    let speed = 0;
    function setSpeed(s){
        return speed = s;
    }
    function getSpeed(){
        return speed;
    }
    function accelerate(){
        return speed+=10;
    }
    function decelerate(){ //速度不能为负数
        return speed>0?speed-=10:speed;
    }
    function getStatus(){
        return speed>0?'running':'stop';
    }
    return {
        "setSpeed"   : setSpeed,
        "getSpeed"   : getSpeed,
        "accelerate" : accelerate,
        "decelerate" : decelerate,
        "getStatus"  : getStatus
    }
})();

3、下面这段代码输出?如何输出delayer: 0, delayer:1...

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

用let

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

用闭包

for(var i=0;i<5;i++){
    (function(t){
        return setTimeout(function(){
                    console.log('delayer:' + t );
                }, 0);
    })(i);
    console.log(i);
}
上一篇下一篇

猜你喜欢

热点阅读