javascript闭包原理及应用

javascript闭包原理及应用,第1张

  官方对闭包的解释是:一个拥有许多变量和绑定了这些变量的环境的表达式(通常是一个函数),因而这些变量也是该表达式的一部分。

  一、javascript闭包的特点:

  1.作为一个函数变量的一个引用,当函数返回时,其处于激活状态。

  2.一个闭包就是当一个函数返回时,一个没有释放资源的栈区。

  简单的说,javascript允许使用内部函数---即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问它们所在的外部函数中声明的所有局部变量、参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。

  javascript闭包原理及应用,javascript闭包原理及应用,第2张

  二、javascript闭包的原理

  闭包是指有权访问另一个函数作用域中的变量的函数。根据下面的代码示例来理解什么是闭包,在add函数内部的匿名函数中,访问到外部函数的变量outerArg,在执行add(10)之后外部函数返回了,并且将内部的匿名函数赋值给了变量addTen,此时通过addTen调用函数,依然可以访问到outerArg,也就是10。这个闭包中的变量,只能通过调用addTen函数访问,无法通过其他渠道访问到,下面代码最后一行通过输出属性的方式尝试访问结果是输出undefined。

  outerArg是属于add函数的作用域中的变量,addTen有权访问add函数作用域中的变量,因此addTen是一个闭包。闭包产生的本质是:在一个函数(外部函数)内部定义的函数(内部函数)会将外部函数作用域中的活动对象添加到自己的作用域链中,下面代码中inner函数将add函数的outerArg添加到自己的作用域链上。在add函数执行完之后,其执行环境会被销毁,但由于inner函数还在引用outerArg,所以outerArg不会被销毁,依然保留在inner函数的作用域链中。直到inner函数(addTen函数)被销毁之后,outerArg才会跟着其作用域链一起被销毁。由于闭包变量是位于作用域链上,因此必须调用闭包函数进入其作用域之后才能访问到闭包变量。

  funcTIon add(outerArg) {

  funcTIon inner(innerArg) {

  return innerArg + outerArg;

  }

  return inner;

  }

  var addTen = add(10);

  console.log(addTen(1)); // 输出11

  console.log(addTen(2)); // 输出12

  console.log(addTen(3)); // 输出13

  console.log(addTen.outerArg); // undefined123456789101112

 三、javascript闭包的应用

  javascript闭包的应用1

  这个是我在用js模拟排序算法过程遇到的问题。我要输出每一次插入排序后的数组,如果在循环中写成

  setTImeout(funcTIon() { $(“proc”).innerHTML += arr + “《br/》”; }, i * 500);

  会发现每次输出的都是最终排好序的数组,因为arr数组不会为你保留每次排序的状态值。为了保存会不断发生变化的数组值,我们用外面包裹一层函数来实现闭包,用闭包存储这个动态数据。下面用了2种方式实现闭包,一种是用参数存储数组的值,一种是用临时变量存储,后者必须要深拷贝。所有要通过闭包存储非持久型变量,均可以用临时变量或参数两种方式实现。

  《!DOCTYPE html PUBLIC “-//W3C//DTD XHTML 1.0 Transitional//EN” “http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd”》

  《html xmlns=“http://www.w3.org/1999/xhtml”》

  《head》

  《title》《/title》

  《script type=“text/javascript”》《!--

  var arr = [4, 5, 6, 8, 7, 9, 3, 2, 1, 0];

  var $ = function(id) { return document.getElementById(id); }

  var Sort = {

  Insert: function() {

  for (var i = 1; i 《 arr.length; i++) {

  for (var j = 0; j 《 i; j++) {

  if (arr[i] 《 arr[j]) {

  arr[i] = [arr[j], arr[j] = arr[i]][0];

  }

  }

  setTimeout((function() {

  var m = [];

  for (var j = 0; j 《 arr.length; j++) {

  m[j] = arr[j];

  }

  return function() {

  $(“proc”).innerHTML += m + “《br /》”;

  }

  })(), i * 500);

  //or 写成下面这样也可以

  /*

  setTimeout((function(m) {

  return function() {

  $(“proc”).innerHTML += m + “《br /》”;

  }

  })(arr.join(“,”)), i * 500);

  */

  }

  return arr;

  }

  }

  // --》《/script》

  《/head》

  《body》

  《div》

  var a = [4, 5, 6, 8, 7, 9, 3, 2, 1, 0];《/div》

  《div》

  《input type=“button” value=“插入排序” onclick=“Sort.Insert();” /》

  《/div》

  Proc:《br /》

  《div id=“proc”》

  《/div》

  《/body》

  《/html》

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/dianzi/2717678.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-08-17
下一篇 2022-08-17

发表评论

登录后才能评论

评论列表(0条)

保存