3 javascript闭包学习总结

闭包几个思想

javascript中有两种作用域,全局和局部,由于局部作用域的存在导致外部无法访问函数内部变量,从而出现了闭包思想。闭包的关键是作为沟通函数内外部的数据桥梁。

//一个实现
        function closure() {
            var innerVar = 0;
            function inner() {
                return  ++innerVar;//可以直接修改innervar的值
            }
            return inner;
        }
        var quote = closure();
        echo(pclosure1, quote());//1
        echo(pclosure1, quote());//2

js是函数作用域的,即一个function就是一个局部作用域,innerVar在函数作用域里面。但是希望能操作该内部变量。 那么其内部的函数就可以访问并修改这个局部变量。所以在第二次调用时,第一次调用的结果仍然保存着。

2:闭包中涉及的静态与动态作用于思想

var name = "xiaofu";
var person = function(lastname){
    var name = 'yang';

    function personName(){
        return name + lastname;
    }
    return personName;
}
var pName = person();
pName("xiaoming");

js 中一个function就是一个作用域,所以personName在person这个函数的作用域里面。但是调用的是在这个作用域的外面,那么当personName执行的时候,它里面的name取的是person这个作用域还是最外层的作用域呢?

如果是静态作用域则调用的是person里面的 name, 如果是动态作用域则调用的是外层的name(“xiaofu”);而不是”yang”。

闭包就是用来实现静态作用域的一种方式,即通过闭包将函数和它声明时的作用域保存下来,这样在调用的时候取到的就是声明时所在作用域 而不是调用时的作用域。
this
this则与变量有点不同,即this采用的是类似于动态作用域的情况。js里面一切都是对象,所以函数也都是某个对象的方法,如果没有显示指定则是全局对象window。

var person = {
    fullname: function{
        console.log(this);
    },
    printAge: function(){
        console.log(this);
    }
}
person.fullname();      //this指向person
var age = person.printAge;
age();                  //this指向window(浏览器中)

将person.printAge赋值给age之后,再执行age(),此时age没有显示指定调用对象则默认是window(浏览器环境)。所以this并不是声明所在的环境。

3箭头函数(es6)

es6中新增了箭头函数,箭头函数与通过function声明的函数不同,它的this是使用的声明时上下文中的this.并且不可通过apply, call等改变所以在使用箭头函数时一定要注意this指向问题。

4 闭包的应用—立即执行函数

1:关键立即执行函数本身即是一个闭包
2:闭包可以操作所在函数中的变量(利用这点锁住每次循环的变量值到内存中)
有个网友问了个问题,如下的html,为什么每次输出都是5,而不是点击每个p,就alert出对应的1,2,3,4,5。

<html >     
<head>     
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />     
<title>闭包演示</title>     
<script type="text/javascript">     

function init() {     
    var pAry = document.getElementsByTagName("p");     
    for( var i=0; i<pAry.length; i++ ) {     
         pAry[i].onclick = function() {     
         alert(i);     
    }     
  }     
}     
</script>     
</head>     
<body onload="init();">     
<p>产品一</p>     
<p>产品二</p>     
<p>产品三</p>     
<p>产品四</p>     
<p>产品五</p>     
</body>     
</html>     

使用闭包可以解决异步加载问题:,

方法1、将变量 i 保存给在每个段落对象(p)上
“`
function init() {
var pAry = document.getElementsByTagName(“p”);
for( var i=0; i


**方法2、将变量 i 保存在匿名函数自身** 
 ```
function init2() {     
  var pAry = document.getElementsByTagName("p");     
  for( var i=0; i<pAry.length; i++ ) {       
   (pAry[i].onclick = function() {     
        alert(arguments.callee.i);     
    }).i = i;     
  }     
}     

方法3、加一层闭包,i以函数参数形式传递给内层函数

function init3() {     
  var pAry = document.getElementsByTagName("p");     
  for( var i=0; i<pAry.length; i++ ) {     
   (function(arg){         
       pAry[i].onclick = function() {         
          alert(arg);     
       };     
   })(i);//调用时参数     
  }     
}     

方法4、加一层闭包,i以局部变量形式传递给内存函数

function init4() {     
  var pAry = document.getElementsByTagName("p");     
  for( var i=0; i<pAry.length; i++ ) {       
    (function () {     
      var temp = i;//调用时局部变量     
      pAry[i].onclick = function() {       
        alert(temp);       
      }     
    })();     
  }     
}     

方法5、加一层闭包,返回一个函数作为响应事件(注意与3的细微区别)

function init5() {     
  var pAry = document.getElementsByTagName("p");     
  for( var i=0; i<pAry.length; i++ ) {       
   pAry[i].onclick = function(arg) {     
       return function() {//返回一个函数     
       alert(arg);     
     }     
   }(i);     
  }     
}    

方法6、用Function实现,实际上每产生一个函数实例就会产生一个闭包

function init6() {     
    var pAry = document.getElementsByTagName("p");     
    for( var i=0; i<pAry.length; i++ ) {       
      pAry[i].onclick = new Function("alert(" + i + ");");//new一次就产生一个函数实例    
    }     
}    

方法7、用Function实现,注意与6的区别

function init7() {     
    var pAry = document.getElementsByTagName("p");     
    for( var i=0; i<pAry.length; i++ ) {     
         pAry[i].onclick = Function('alert('+i+')')    
    }     
}     
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值