zoukankan      html  css  js  c++  java
  • 8-JS闭包、回调实例

    1.回调

    javascipt中,函数回调一般用于以下几种场景:

    1.异步执行(例如读取文件,进行HTTP请求)
    2.同步(阻塞)
    3.事件监听和处理
    4.设置超时和时间间隔的方法
    

    异步例子(使用AJAX加载XML文件的示例,并且使用了call()函数,在请求对象(requested object)上下文中调用回调函数。):

    function fn(url, callback){
      var httpRequest;    //创建XHR
      httpRequest = window.XMLHttpRequest ? new XMLHttpRequest() :   //针对IE进行功能性检测
        window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP") : undefined;
      
      httpRequest.onreadystatechange = function(){
       if(httpRequest.readystate === 4 && httpRequest.status === 200){  //状态判断4和200表示执行该语句
         callback.call(httpRequest.responseXML); 
       }
      };
      httpRequest.open("GET", url);
      httpRequest.send();
    }
     
    fn("text.xml", function(){    //调用函数
     console.log(this);   //此语句后输出
    });
     
    console.log("this will run before the above callback.");  //此语句先输出
    

    异步处理,意味着我们开始请求时,就告诉它们完成之时调用我们的函数。在实际情况中,onreadystatechange事件处理程序还得考虑请求失败的情况,这里我们是假设xml文件存在并且能被浏览器成功加载。这个例子中,异步函数分配给了onreadystatechange事件,因此不会立刻执行。

    同步例子(func1代码执行完成后才执行func2):

    var func1=function(callback){
      //do something.
      (callback && typeof(callback) === "function") && callback();
    }
     
    func1(func2);
      var func2=function(){
    }
    

    提醒:回调函数是个闭包

    2.闭包

    官方释义:闭包是指那些能够访问独立(自由)变量的函数 (变量在本地使用,但定义在一个封闭的作用域中)。换句话说,这些函数可以“记忆”它被创建时候的环境。

    闭包允许将函数与其所操作的某些数据(环境)关连起来。这显然类似于面向对象编程。在面对象编程中,对象允许我们将某些数据(对象的属性)与一个或者多个方法相关联。

    官方实例:假设我们想在页面上添加一些可以调整字号的按钮。一种方法是以像素为单位指定 body 元素的 font-size,然后通过相对的 em 单位设置页面中其它元素(例如页眉)的字号:

    body {
      font-family: Helvetica, Arial, sans-serif;
      font-size: 12px;
    }
    
    h1 {
      font-size: 1.5em;
    }
    
    h2 {
      font-size: 1.2em;
    }
    

    我们的交互式的文本尺寸按钮可以修改 body 元素的 font-size 属性,而由于我们使用相对的单位,页面中的其它元素也会相应地调整。

    以下是 JavaScript:

    function makeSizer(size) {
         return function() {
            document.body.style.fontSize = size + 'px';
        };
    }
        
    var size12 = makeSizer(12);
        
    var size14 = makeSizer(14);
        
    var size16 = makeSizer(16);
    

    size12,size14 和 size16 为将 body 文本相应地调整为 12,14,16 像素的函数。我们可以将它们分别添加到按钮上(这里是链接)。如下所示:

    document.getElementById('size-12').onclick = size12;
    document.getElementById('size-14').onclick = size14;
    document.getElementById('size-16').onclick = size16;
    
    <a href="#" id="size-12">12</a>
    <a href="#" id="size-14">14</a>
    <a href="#" id="size-16">16</a>
    
    function makeSizer(size) {
      return function() {
        document.body.style.fontSize = size + 'px';
      };
    }
    
    var size12 = makeSizer(12);
    var size14 = makeSizer(14);
    var size16 = makeSizer(16);
    
    document.getElementById('size-12').onclick = size12;
    document.getElementById('size-14').onclick = size14;
    document.getElementById('size-16').onclick = size16;
    

    附:闭包的模块模式(使用闭包模拟私有方法)

    var makeCounter = function() {
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        increment: function() {
          changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
      }  
    };
    
    var Counter1 = makeCounter();
    var Counter2 = makeCounter();
    console.log(Counter1.value()); /* logs 0 */
    Counter1.increment();
    Counter1.increment();
    console.log(Counter1.value()); /* logs 2 */
    Counter1.decrement();
    console.log(Counter1.value()); /* logs 1 */
    console.log(Counter2.value()); /* logs 0 */
    

    此种私有方法不仅仅有利于限制对代码的访问:还提供了管理全局命名空间的强大能力,避免非核心的方法弄乱了代码的公共接口部分。

    注意:不要在循环中创建闭包

  • 相关阅读:
    算法----(1)冒泡排序
    淘宝爬虫
    爬虫_豆瓣电影top250 (正则表达式)
    爬虫_猫眼电影top100(正则表达式)
    Android 简单调用摄像头
    Android 简单天气预报
    思维模型
    This view is not constrained, it only has designtime positions, so it will jump to (0,0) unless you
    Android studio preview界面无法预览,报错render problem
    Android studio 3.1.2报错,no target device found
  • 原文地址:https://www.cnblogs.com/fengxuefei/p/6250535.html
Copyright © 2011-2022 走看看