也说闭包

2016-08-05  本文已影响24人  进击的前端

好像闭包也是JS绕不过的一个问题。

闭包的定义

第一个是闭包的形式。简而言之就是一个函数返回被外部调用的函数,makeFunc是一个闭包,它返回了displayName的定义,而这个displayName能够记录makeFunc运行的时候的局部变量。

function makeFunc() {
  var name = "Mozilla";
  function displayName() {
    alert(name);
  }
  return displayName;
}

var myFunc = makeFunc();
myFunc();

闭包的用途

产生不同的回调函数

function makeSizer(size) {
  return function() {
    document.body.style.fontSize = size + 'px';
  };
}
var size12 = makeSizer(12);
var size14 = makeSizer(14);
var size16 = makeSizer(16);
document.getElementById('size-12').onclick = size12;
document.getElementById('size-14').onclick = size14;
document.getElementById('size-16').onclick = size16;

闭包模拟私有方法

私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。

var Counter = (function() {
  var privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  return {
    increment: function() {
      changeBy(1);
    },
    decrement: function() {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    }
  }   
})();

console.log(Counter.value()); /* logs 0 */
Counter.increment();
Counter.increment();
console.log(Counter.value()); /* logs 2 */
Counter.decrement();
console.log(Counter.value()); /* logs 1 */

首先Count = (function(){})(),立即执行函数,得到return的一个对象,对象保存了不同的函数,而函数能够访问闭包中的元素。同时,闭包中的私有变量并不能被外界访问。

闭包的循环陷阱

function showHelp(help) {
  document.getElementById('help').innerHTML = help;
}
function setupHelp() {
  var helpText = [
      {'id': 'email', 'help': 'Your e-mail address'},
      {'id': 'name', 'help': 'Your full name'},
      {'id': 'age', 'help': 'Your age (you must be over 16)'}
    ];
  for (var i = 0; i < helpText.length; i++) {
    var item = helpText[i];
    document.getElementById(item.id).onfocus = function() {
      showHelp(item.help);
    }
  }
}
setupHelp();

这个是典型的循环问题,因为共享一个变量,所以每次真正调用的是。

闭包的缺点

除了循环陷阱,性能和内存也是有问题的。

参考

MDN

上一篇 下一篇

猜你喜欢

热点阅读