欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

详解JavaScript之闭包

程序员文章站 2022-03-04 15:33:21
...
闭包 : 闭包就是一个函数引用另外一个函数的变量,因为变量被引用着所以不会被回收,因此可以用来封装一个私有变量。

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

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

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之闭包的详细内容,更多请关注其它相关文章!

相关标签: JavaScript 闭包