JS--闭包--渡一教育(视频笔记)

闭包

当内部函数被保存到外部时,将会生成闭包。闭包会导致原有作用域链不释放,造成内存泄露。

闭包小例子:

function a(){
   var num = 100;
   function b(){
      num ++;
      console.log(num);
   }
   return b;//或者demo = b;
}
//a 的AO被销毁
var demo = a(); //执行a,将函数b保存在demo中
demo(); //执行b,打印出101
//此时a的AO已经被销毁,第一次执行完b之后,将a的AO里面num值改为101,b的AO被销毁
demo(); //再执行b,打印出102

闭包的作用

1、实现公有变量
     eg : 函数累加器

function add(){
   var count = 0;
   function demo(){
      count ++;
      sonsole.log(count);
   }
   return demo();
}
var counter = add();
counter();
counter();
counter();
function test(){
   var num = 100;
   function a(){
      num ++;
      console.log(num);
   }
   function b(){
      num --;
      console.log(num);
   }
   return  [a,b];
}
var myArr = test();
myArr[0](); //打印101
myArr[1]{}; //打印100
//a和b共用一个test的AO

2、可以做缓存(存储结构)
     eg : eater

function eater(){
   var food = "";
   var obj = {
      eat : function (){
         console.log("i am eating" + food);
         food = "";
      }, //对象的方法
      push : function(myFood){
         food = myFood;
      }
   }
   return obj;
}
var eater1 = eater();
eater1.push('banana');
eater1.eat();

3、可以实现封装,属性私有化
     eg : Person();

4、模块化开发,防止污染全局变量

 

闭包的防范

闭包会导致多个执行函数共用一个公有变量,如果不是特殊需要,应尽量防止这种情况发生。

function test(){
   var arr = [];
   for (var i = 0; i < 10; i ++){
      arr[i] = function (){
         document.write(i + " ");
      }//执行test函数时并不执行里面这个函数体,
   }//循环到i = 10;跳出循环
   return arr;
}
var myArr = test();//先执行完test函数,此时i = 10;
for(var j = 0; j < 10; j ++){
   mrArr[j]();//此时才执行function (){document.write(i + "");}
}
//程序结果打印十个10
解决方法:利用立即执行函数的特性
function test(){
   var arr = [];
   for(var i = 0; i < 10; i ++){
      (function (j){
          arr[j] = function (){
             document.write(j + " ");
          }
       }(i));//立即执行函数是读到它的时候就执行,不需要先调用
   }
   return arr;
}
var myArr = test();
for(var j = 0; j < 10; j ++){
   myArr[j]();
}

试题1:无序列表,使用原生JS, addEventListener,给每个li元素绑定一个click事件,输出他们的顺序

function test(){
   var liCollection = document.getElementByTagName('li');
   for(var i = 0; i < liCollection.length; i++){
      (function (j){
         liCollection[j].onclick = function(){ //把函数绑定到了每个li元素(外部)
            console.log(i);
            //console.log(this.innerText);点击打印li元素里的内容
         }
      }(i))
   }
}
test();

 
定义和用法:
charCodeAt()方法可返回指定位置的字符的Unicode编码。这个返回值是0-65535之间的整数。(当返回值是 <=255 时,为英文;当返回值 >255 时为中文、日文等非常规字符)。
charCodeAt() 与 charAt() 方法执行的操作相似,只不过前者返回的是位于指定位置的字符的编码,而后者返回的是字符子串。
语法:
stringObject.charCodeAt(index)
index 必需。表示字符串中某个位置的数字,即字符在字符串中的下标,从0开始。负数或大于字符串长度时返回NaN;
eg:

<script type="javascript/text">
    var str = "Hello world!"
    document.write(str.charCodeAt(1)); //输出101
</script>

 
试题2:写一个方法,求一个字符串的字节长度。(提示:字符串有一个方法 charCodeAt(); 一个中文占两个字节,一个英文占一个字节)

function retByteslen(target){
    var count = 0;
    for(var i = 0; i < target.length; i++){
        if(target.charCodeAt(i) <= 255){
            count ++;
        }else if(target.charCodeAt(i) > 255){
            count += 2;
        }
    }
    console.log(count);
}
//简化
function retByteslen(target){
    var count,len;
    count = len = target.length;
    for(var i = 0; i < len; i++){
        if(target.charCodeAt(i) > 255){
             count ++;
        }
    }
    console.log(count);
}

 
试题3:写出下列程序的执行结果

var f = (
    function f(){
        return "1";
    },
    function g(){
        return 2;
    }
)();
console.log(typeof f); //number
//var a=(2,3); a的值为3
//先计算逗号前的表达式,在计算逗号后面的表达式,最后返回逗号后面表达式的结果

 
试题4:写出下列程序的执行结果

var x = 1;
if(function f() {}){ //(function f() {})在括号中,变成表达式,不是函数定义,f消失
    x += typeof f; //未经声明的变量f只有在typeof里面不报错,返回string类型的undefined
    //1 + undefined(undefined类型) 结果为 NaN
}
console.log(x); //1undefined

 
作业:

1、运行 test()new test() 的结果分别是什么?
   var a = 5;
   function test(){
      a = 0;
      alert(a);
      alert(this.a);
      var a;
      alert(a);
   }

2、分析下面的JavaScript代码段
   function employee(name,code){
       this.name = "wangli";
       this.code = "A001";
   }
   var newemp = new employee("zhangming",'A002');
   document.write("雇员姓名:"+ newemp.name+"<br>");
   document.write("雇员代号:"+ newemp.code+"<br>");
   输出结果是(A).(单选)
   A.雇员姓名:wangli  雇员代号:A001
   B.雇员姓名:zhangming  雇员代号:A002
   C.雇员姓名:null  雇员代号:null
   D.代码有错误,无输出结果

3、a = 100;
   function demo(e){
       function e(){}
       arguments[0] = 2; //第一个形参值赋2
       document.write(e); //打印2
       if(a){ //现在不允许在if中定义函数(题中假设允许)
           var b = 123;
           function c(){
               //
           }
       }
       var c;
       a = 10;
       var a;
       document.write(b); //打印undefined
       f = 123;
       document.write(c); //打印function c(){}
       document.write(a); //打印10
   }
   var a;
   demo(1);
   document.write(a); //打印100
   document.write(f); //打印123

4var str = "abc";
   str += 1;
   var test = typeof(str);
   if(test.length == 6){
       test.sign = "typeof的返回结果可能为String"}
   document.write(test.sign);//undefined

5function Person(name, age, sex){
       var a = 0;
       this.name = name;
       this.age = age;
       this.sex = sex;
       function sss(){
           a ++;
           document.write(a);
       }
       this.say = sss;
   }
   var oPerson = new Person();
   oPerson.say();//1
   oPerson.say();//2
   var oPerson1 = new Person();
   oPerson1.say();//1

6、改为可以输出0-9的形式
   function bb(){
       var arr = [];
       for(var i = 0; i < 10; i++){
           arr[i] = function(){
                document.write(i);
           }
       }
       return arr;
   }
   var arr1 = bb();
   for(var i = 0; i < 10; i++){
       arr1[i]();
   }

7var str = false + 1;
   document.write(str);
   vae demo = false == 1;
   document.write(demo);
   if(typeof(a)&&-true + (undefined) + ""){
       document.write('基础扎实')}
   if(11 + "11" * 2 ==33){
       document.write('基础扎实')}
   !!" " + !!"" - false||document.write('emmmm')
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值