zoukankan      html  css  js  c++  java
  • 对于闭包的一些理解

    对于闭包的理解首先需要对作用域的进行了解,其中最重要的一点是对于JS函数运行在它们被定义的作用域里而不是被执行的作用域里: 

    function f1() {
      var a = 1;
      f2();
      function f2() {
        alert(a);
      }
    }
    f1();代码一

    function f1() {
      var a = 1;
      f2();
    }
    function f2() {
      alert(a);
    }
    f1();代码二

    代码一显示a=1,代码二显示a未定义。

    闭包:指外部函数无法获得内部函数的值,但内部函数的下一级可以获得并返回。

    一.关于this:举连个例子:

    1.

    function Hero(name) {
        	this.name = name;
    }
    var h = Hero("pcd");
    var h = new Hero("pcd");
    

    不使用new时,h值为该函数的返回值,为undefined,this指向全局变量window。

    但创建一个对象时,this指向这个对象。

    2.

    var name = "The Window";
    var object = {
      name: "My Object",
      getNameFunc: function() {
        return function() {
          return this.name;
        }
      }
    }
    console.log(object.getNameFunc()());

    var name = "The Window";
    var object = {
      name: "My Object",
      getNameFunc: function() {
        var that = this;
        return function() {
          return that.name;
        }
      }
    }
    console.log(object.getNameFunc()());

    当函数被作为某个对象的方法调用时,this指向那个对象,在全局函数中this等于window。

    二.

    function fun(n,o) {
      console.log(o)
      return {
        fun:function(m){
          return fun(m,n);
        }
      };
    }
    var a = fun(0);  a.fun(1);  a.fun(2);  a.fun(3);//undefined,?,?,?
    var b = fun(0).fun(1).fun(2).fun(3);//undefined,?,?,?
    var c = fun(0).fun(1);  c.fun(2);  c.fun(3);//undefined,?,?,?
    

    答案为:

    //答案:
    //a: undefined,0,0,0
    //b: undefined,0,1,2
    //c: undefined,0,1,1
    View Code

    return fun(m,n)为立即执行函数;匿名函数对fun活动对象的引用。

    题目详解链接:http://www.cnblogs.com/xxcanghai/p/4991870.html

    三.模拟块级作用域

    javascript内有块级作用域,例:

    if(true) {
        var color = "blue";
    }
    
    console.log(color);//blue
    
    for (var i=0; i < 5; i++){
        console.log(i);
    }
    
    console.log(i);//5
    

    在函数中造成在存在该值,例:

    function outputNumbers(count){
        for (var i=0; i < count; i++){
            console.log(i);
        }            
        console.log(i);   //count
    }
    
    outputNumbers(5);    
    

    为了使outputNumbers()中的其他地方不在有i值,将其放入模拟块级作用域中

    function outputNumbers(count){
    	(function() {
    		for (var i=0; i < count; i++){
            	  console.log(i);
        	     }
    	})();
         
        console.log(i);   //错误
    }

    则在outputNumbers()中的其他地方不存在有i值。

    四.内存泄露

    function assignHandler() {
        var element = document.getElementById("some_element");
        element.onclick = function() {
            alert(element.id);
        }
    }
    

    这是一个简单的闭包,作用域中保存着一个HTML元素,造成循环引用,导致该对象无法被销毁。

    function assignHandler() {
        var element = document.getElementById("some_element");
        var id = element.id;
        element.onclick = function() {
            alert(id);
        }
        element = null;
    }
    

    创建一个id为非Dom元素,消除循环引用。

    七.闭包造成内存积累

    function F() {
        var arr = [], i;
        for(i = 0; i < 3; i++) {
            arr[i] = function() {
                return i;
            }
        }
        return arr;
    }
    
    var arr = F();
    arr[0];//3
    arr[1];//3
    arr[2];//3
    

    执行arr[0],arr[1],arr[2]时return的i已经是for循环结束之后,for没有块级作用域,此时的i为3。

    function setup(x) {
        var i = 0;
        return function() {
            return x[i++];
        }
    }
    var next = setup(['a', 'b', 'c']);
    
    next();//a
    next();//b
    next();//c
    

    在执行next()时,return x[i++];中的i是从return function() {}这个局部内获得的,因为是闭包,造成i的累加。

  • 相关阅读:
    echarts使用
    Nutch插件系统
    linux命令总结
    linux命令行快捷键
    每日一笔
    Hadoop参数调优
    rsync用于同步目录
    hadoop遇到的问题(汇总)
    linux历史命令
    hadoop 编译代码及运行
  • 原文地址:https://www.cnblogs.com/pcd12321/p/5263420.html
Copyright © 2011-2022 走看看