zoukankan      html  css  js  c++  java
  • 闭包.词法作用域#

    JS程序的执行过程.
    1.词法分析 .  语法分析阶段:变量声明(赋值阶段在执行阶段进行);函数声明带函数赋值.
    2.函数表达式的变形
    1. //函数表达式的变形
    2. var fn=function foo(){
    3. console.log("abc");
    4. };
    5. fn();//"abc" foo();//报错
     
    2.词法作用域,作用域链,变量查找过程
    按照书写个还是决定了变量可访问的范围,跟调用方式无关
    1. var height =10;
    2. setTimeout(function(){
    3. var height2=30;
    4. setTimeout(function(){
    5. var height1 =80;
    6. console.log(height2);//30
    7. });
    8. console.log(height1);//获取不到height1
    9. });
    3.函数具有独立的作用域,在函数内部的程序执行过程,也会有一套完整的预解析的步骤.
     
    4.拷贝创建对象
    1. /*拷贝创建对象的高级使用方式*/
    2. function hightExtend(){
    3. var key =0, i =0, len = arguments.length;
    4. target =null;
    5. if(len ==0){
    6. returnfalse;
    7. }elseif(len ==1){
    8. return arguments[0];
    9. }else{
    10. i++;
    11. target = arguments[0];
    12. for(; i < len; i++){
    13. for(key in arguments[i]){
    14. target[key]= arguments[i][key];//把后面传入的对象遍历一下,但遍历每一个对象的属性
    15. //添加到target元素上
    16. }
    17. }
    18. }
    19. }
    1. //5.历史遗留问题
    2. if(true){
    3. function foo1(){
    4. console.log(foo1);
    5. }
    6. }else{
    7. function foo2(){
    8. console.log(foo2);
    9. }
    10. }
    11. //在ff.chrome中打印结果为f1,在旧版本中打印结果为f2
    12. //规则规范,不允许在语法块中声明函数
    13. 6.跨作用域访问变量
    1. /*
    2. * 查找作用域中的变量:首先查找当前作用域是否定义了该变量,若果定义了就不会再继续查找
    3. * */
    4. function foo(a,b){
    5. console.log(a);}
    6. foo(1,4);
    7. //函数的参数是在foo作用域执行的时候
    8. //预解析:分析a是一个采纳数所以会向当前作用域添加一个变量a并且给a赋值,值是实参的值
    9. //代码执行;参数已经有值了 可以直接获取
    10. var num =10;
    11. function fn(num){
    12. console.log(num);//undefined
    13. // 首先查找当前作用域是否定义了num
    14. }
     
    3.闭包  模块化   闭包最常见的使用场景
    1. //沙箱:模块化,沙箱是一个隔离的环境,最大的好处就是避免全局变量的污染.
    2. var model =(function(){//一个匿名的立即执行函数
    3. var price =900;//这是一个model局部的变量,外界无法访问,无法修改
    4. //有效的保障了属性的安全性
    5. return{
    6. pay:function(money){
    7. if(money < price){
    8. console.log("您的消费不够,请继继续消费");
    9. }else{
    10. console.log("恭喜成为VIP");
    11. }
    12. }
    13. }
    14. })();
    15. console.log(model.pay(800));//"消费不够.." undefined
    16. model.pay(1000);//"VIP..."
    17. //千万注意不用打印,pay函数本身就有输出,如果在console.log中
    18. //会输出函数的返回值.
     
    1. //在面向对象中使用沙箱
    2. //应用场景:在页面初始化的时候要用到f1,f2,f3三个函数
    3. //这三个函数不想让外界访问,需要把这单个方法声明成为构造函数
    4. //内部私有的变量
    5. var songManger =(function(){
    6. function f1(){
    7. console.log("函数f1的方法");
    8. }
    9. function f2(){
    10. console.log("函数f2的方法");
    11. }
    12. function f3(){
    13. console.log("函数f4的方法");
    14. }
    15. functionSongManger(){//声明一个构造函数
    16. }
    17. SongManger.prototype={//在原型对象上扩展方法
    18. init:function(){
    19. f1();
    20. f2();
    21. f3();
    22. }
    23. };
    24.   // return SongManger;//注意这个返回的是构造函数,使用之前需要先实例化一下
    25. returnnewSongManger;//把构造函数返回,实例化一下,这样外边就不需要实例化了
    26. })();
    27. songManger.init();//
     
    1. /*
    2. * 闭包实现缓存
    3. * 属性:有个键--值 --->所以可以将缓存数据存放在一个对象中
    4. * 方法:缓存存储 setCache
    5. * 缓存的获取 getCache
    6. * */
    7. function configCache(){
    8. var obj={};//设置一个内部的对象 用来存储缓存数据;这个属性是私有的
    9. //对外暴露两个公共的方法
    10. return{
    11. setCache:function(k,v){//设置缓存
    12. obj[k]=v;
    13. },
    14. getCache:function(k){//获取缓存
    15. return obj[k];
    16. }
    17. };
    18. }
    19. var conf = configCache();
    20. console.log(conf);
    21. conf.setCache(1,'sdwqecwqv');
    22. console.log(conf.getCache(1));//sdwqecwqv
    23. /*
    24. * 注意下面这种情况,两次configCache()会产生不同的执行环境
    25. * */
    26. configCache().setCache(1,'sdwqecwqv');
    27. console.log(configCache().getCache(1));//undefined
    28. /*
    29. * 使用立即执行函数
    30. * */
    31. var cacheConfig =(function(){
    32. var obj={};
    33. return{
    34. setCache:function(k,v){
    35. obj[k]=v;
    36. },
    37. getCache:function(k){
    38. return obj[k];
    39. }
    40. }
    41. })();
     
    1. // 给所有的 li 提供点击事件, 在点击后 弹出目录中的文本内容
    2. <body>
    3. <ul>
    4. <li>aaa</li>
    5. <li>bbb</li>
    6. <li>ccc</li>
    7. <li>ddd</li>
    8. <li>eee</li>
    9. </ul>
    10. </body>
    11. <script>
    12. var list = document.getElementsByTagName('li');
    13. for(var i =0; i < list.length; i++){
    14. list[ i ].onclick =function(){
    15. //alert(i);//i=5
    16. //alert( list[ i ].innerHTML );//报错
    17. //alert(this.innerHTML);//一种解决方案
    18. //list[4]:eee list[5]:undefined
    19. };
    20. }
    21.  
    22. </script>
    1. //第二种解决方案:闭包
    2. // for ( i = 0; i < list.length; i++ ){
    3. var j=i;
    4. // list[ i ].onclick = (function (j) {
    5. // return function (){
    6. // alert(list[j].innerHTML);
    7. // }
    8. // }(i));
    9. // }
     
     
     
    1. //caller
    2. function fn1(){
    3. console.log(fn1.caller);//打印的是fn1函数体
    4. }
    5. function fn2(){
    6. fn1();
    7. }
    8. fn2();
    9. console.log(fn1.caller);//null caller方法只能在函数调用的时候获取
     
    1. //问题理解的关键: 内层函数保存的j,当执行的时候从哪里取的??
    2. //每次绑定都会执行一个外层函数,都会产生一个新的作用域,内层函数会保存这个新作用域中的变量
    3. var list = document.getElementsByTagName("li");
    4. for(var i=0;i<list.length;i++){
    5. list[i].onclick=(function(){
    6. var j=i;//每次绑定都会执行外层函数,都会保存一个J的变量在内层函数中
    7. returnfunction(){
    8. console.log(list[j].innerHTML);
    9. }
    10. })();
    11. }
    1. //结论:
    2. //闭包保存一个数据,让外层函数执行一次
    3. //闭包保存多个数据,让外层函数执行多次
    4. var list = document.getElementsByTagName('li');
    5. for(var i =0; i < list.length; i++){
    6. //希望每一次绑定的时候,就保存一下当前的索引
    7. // 多次绑定就保存多个索引——>利用闭包,保存多个数据:让外层函数执行多次
    8. list[i].onclick =(function(){
    9. var j=i;
    10. returnfunction(){//内层函数由浏览器帮助我们调用的
    11. alert(list[j].innerHTML);
    12. }
    13. }());//调用了5次,外层函数调用了五次,就会产生5个独立的作用域,这几个作用域中的j变量的值都不一样
    14. }
     
     
     





  • 相关阅读:
    Oracle备份 还原命令
    maven错误解决一:Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.5.1:compile (default-compile)
    maven File encoding has not been set
    maven 错误: 程序包org.junit不存在
    <转>JDBC获取DB元数据
    <转>SQL语句执行顺序说明
    Oracle 创建/删除 表空间、用户、授权
    lucene/solr 修改评分规则方法总结
    Solr入门之(8)中文分词器配置
    Solr入门之(7)Solr客户端界面简介
  • 原文地址:https://www.cnblogs.com/itlyh/p/6012148.html
Copyright © 2011-2022 走看看