首页 >web前端 >js教程 >详解JavaScript之闭包

详解JavaScript之闭包

零到壹度
零到壹度原创
2018-03-26 14:34:331366浏览

闭包 : 闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。

当内部函数在定义它的作用域的数据外部被引用时,就创建了该内部函数的闭包,如果内部函数引用了位于外部函数的变量,当外部函数调用完毕后,这些变量在内存不会被释放,因为闭包需要它们

变量的作用域 :  作用域就两种,全局作用域和局部作用域

var n=999;
function f1(){
  alert(n);
}
f1(); // 999
function f2(){
  var m=999;
}
alert(m); // error
function f3(){
  i=999; // 函数内部声明变量的时候,一定要使用 var 声明变量,如果不用 var,此时改变量就变成全局变量
}
f3();
alert(i); // 999

从外部读取局部变量 : 正常情况下是办不到的,但可以在函数的内部再定义一个函数,这样内部函数就可以访问外部函数的变量。另外,外部函数无法访问内部函数变量,这就是 JavaScript 语言特有的 "链式作用域" 结构

function f1() {
  var n = 999;
  function f2() {
    alert(n);
  }
  return f2;
}
var result = f1();
result(); // 999

闭包可以用在许多地方。它的最大用处有两个,一个是前面提到的可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中

function f1() {
  var n = 999;
  nAdd = function(){ // nAdd 是全局变量
    n += 1;
  }
  
  function f2() {
    alert(n);
  }
  return f2;
}
var result = f1();
result(); // 999
nAdd();
result(); // 1000

1> 由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除

2> 闭包会在父函数外部,改变父函数内部变量的值。所以,如果把父函数当作对象 (object) 使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值

var name = "The Window";
var object = {
  name : "My Object",
  getNameFunc : function() {
    return function() {
      return this.name;
    };
  },
  getNameFunc2 : function() {
    return () => this.name;
  },
  getNameFunc3 : function() {
    this_ = this;
    return function() {
      return this_.name;
    };
  }
};
alert(object.getNameFunc()());  // The Window,this 指向调用的对象,此处执行的时全局 this 
alert(object.getNameFunc2()()); // My Object,使用箭头函数相当于 getNameFunc3 的写法
alert(object.getNameFunc3()()); // My Object
function outerFun() {
  var a =0;
  alert(a);  
}
var a = 4;
outerFun(); // 0
alert(a); // 4
function outerFun() {
  a = 0; // 没有 var,此时 a 是作用于全局变量,将修改全局变量的 a
  alert(a);  
}
var a=4; // 全局变量 a
outerFun(); // 0
alert(a); // 0
function createFunctions() {
  var result = new Array();
  for (var i=0; i < 10; i++) {
    result[i] = function() {
      return i;
    };
  }
  return result;
}
var funcs = createFunctions();
for (var i=0; i < funcs.length; i++) { // 打印出 10 个 10,在 js 中使用 () 才会执行函数
  console.log(funcs[i]());
}

以上是详解JavaScript之闭包的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn