我能正确理解JavaScript闭包吗?

时间:2014-07-18 23:02:56

标签: javascript closures

在函数内部创建的变量不能在函数外部访问。

例如:

function haha()
{
   var a = 5;
}

a不能在哈哈()外面访问。

这就是闭包派上用场的地方:

function haha()
{
    var a = 5;
    return function hahainside(){ }
}
newfunction = hahainside();

现在,如果我调用newfunction(),它可以访问haha()中的“a”变量。

我说错了吗?

我也想知道为什么:

<script>
    function exclusive()
    {
         d = "Robert, Ryo, Yuri";
         function returnfunction() { alert( d ); }
         return returnfunction();
    }
    ryo = exclusive();
    alert(7);
</script>

我也想知道为什么alert(7);没有显示在我的浏览器上。

1 个答案:

答案 0 :(得分:0)

以下是您需要了解的内容:

var a = 0;
function haha(){
  a = 5; // when calling haha `a` is accessible to everything below where var is declared
  return function(){
    a = 10; // same as notes above
  }
}
var newfunc = haha(); // `a` will become 5 where var is declared
newfunc(); // now `a` is 10 where var is declared
console.log(a); // works

未在var a之外声明haha

function haha(){
  var a = 5; // only available in `haha`
  return function(){
    a = 10; // nearly useless - only scoped to `haha`
  }
}
var newfunc = haha(); // `a` will become 5 where var is declared
newfunc(); // now `a` is 10 where var is declared - can't access `a` where `newfunc` is called
console.log(a); // undefined

也许你想要一个构造函数:

function haha(arg){
  var whatever = 'something'; // never accessible in a new instance from outside
  this.a = arg;
  this.hahaInside = function(val){
    this.a = val;
  }
}
var newfunc = new haha(20); // `newfunc.a` is now `20`
newfunc.a = 12; // `newfunc.a` is now `12`
newfunc.hahaInside(10); // newfunc.a is now 10

作为对象:

var haha = {
  a: 5,
  hahaInside: function(val){
    this.a = val;
  }
}

Object中没有私有变量,也没有Constructor参数。您不必将新实例作为Object调用,但您可能需要新实例。为避免编写关键字this

if(!Object.create){
  Object.create = function(o){
    function F(){}
    F.prototype = o;
    return new F;
  }
}
var newfunc = Object.create(haha); // new 'newfunc` is a new instance of `haha`

实际使用,没有关闭:

// assuming 3 radio buttons
var ary = ['a', 'b', 'c'], radioButtons = document.getElementsByName('radButs');
var resultVar = '';
for(var i=0,l=radioButtons.length; i<l; i++){
    radioButtons[i].onclick = function(){
      resultVar = ary[i];
  }
}
// resultVar will always be `'c'` because by the time the click Event is called the loop has run all the through and the scope of `i` is global

闭包可以防止变量的范围更高。在这种情况下全球:

// assuming 3 radio buttons
var ary = ['a', 'b', 'c'], radioButtons = document.getElementsByName('radButs');
var resultVar = '';
for(var i=0,l=radioButtons.length; i<l; i++){
  (function(i){
    radioButtons[i].onclick = function(){
      resultVar = ary[i];
    }
  })(i);
}
// now `resultVar` will be `'a'`, `'b'`, or `'c'` respectively, depending on the radio button that you clicked because  `i` becomes separately scoped at each step of the loop even by the time the click Event is called due to user action

您还可以使用闭包来创建一个伪静态函数,如下所示:

var count = (function(){
  var c = 0;
  return function(){
    return c++;
  }
})();

现在,每当你致电count()时,它都会做到这一点。这样做的原因是因为立即调用自执行函数,在其中定义var c,并返回一个未执行的函数,该函数会增加c最后作用域的位置。