热门标签 | HotTags
当前位置:  开发笔记 > 前端 > 正文

学习JavaScript设计模式(链式调用)

这篇文章主要带领大家学习JavaScript设计模式,其中重点介绍链式调用,感兴趣的小伙伴们可以参考一下

1、什么是链式调用
这个很容易理解,例如:

$(this).setStyle('color', 'red').show();

一般的函数调用和链式调用的区别:调用完方法后,return this返回当前调用方法的对象。

function Dog(){
    this.run= function(){
      alert("The dog is running....");
      return this;//返回当前对象 Dog
    };
    this.eat= function(){
      alert("After running the dog is eatting....");
      return this;//返回当前对象 Dog

    };
    this.sleep= function(){
      alert("After eatting the dog is running....");
      return this;//返回当前对象 Dog

    };
  }
  //一般的调用方式;
/* var dog1 =new Dog();
  dog1.run();
  dog1.eat();
  dog1.sleep();*/
  var dog2 = new Dog();
  dog2.run().eat().sleep();

2、分解链式调用

链式调用其实是两个部分:

1).操作对象(也就是被操作的DOM元素,如上例的$(this))

2).操作方法(具体要做什么事情,如上例的setStyle和show)

如何实现操作对象与操作方法

创建一般的$函数:

function $(){
  var elements = [];
  for(var i= 0,len=arguments.length; i

但是,如果把这个函数改造为一个构造器,把那些元素作为数组保存在一个实例属性中,并让所有定义在构造器函数的prototype属性所指对象中的方法都返回用以调用方法的那个实例的引用,那么它就具有了链式调用的能力。(说了这么多,就是在每个方法最后return this;),

我首先需要把这个$函数改为一个工厂方法,它负责创建支持链式调用的对象。这个函数应该能接受元素数组形式的参数,以便我们能够使用与原来一样的公用接口。这样以来,它就具有了进行链式调用的能力。

改造后如下:

(function(){
  function _$(els){
    this.elements = [];//把那些元素作为数组保存在一个实例属性中,
    for(var i= 0, len=els.length; i

在最后return this,这就将调用方法的对象传给调用链上的下一个方法。

3、模拟jquery底层链式编程

// 块级作用域
//特点1 程序启动的时候 里面的代码直接执行了
//特点2 内部的成员变量 外部无法去访问 (除了不加var修饰的变量)

(function(window , undefined){
  // $ 最常用的对象 返回给外界 大型程序开发 一般使用'_'作为私用的对象(规范)
  function _$(arguments){
    //实现代码...这里仅实现ID选择器
    // 正则表达式匹配id选择器
    var idselector = /#\w+/ ;
    this.dom ;   // 此属性 接受所得到的元素
    // 如果匹配成功 则接受dom元素  arguments[0] = '#inp'
    if(idselector.test(arguments[0])){
      this.dom = document.getElementById(arguments[0].substring(1));
    } else {
      throw new Error(' arguments is error !');
    }
  };

  // 在Function类上扩展一个可以实现链式编程的方法
  Function.prototype.method = function(methodName , fn){
    this.prototype[methodName] = fn ;
    return this ; //链式编程的关键
  }

  // 在_$的原型对象上 加一些公共的方法
  _$.prototype = {
    constructor : _$ ,
    addEvent:function(type,fn){
      // 给你的得到的元素 注册事件
      if(window.addEventListener){// FF 
        this.dom.addEventListener(type , fn);
      } else if (window.attachEvent){// IE
        this.dom.attachEvent('on'+type , fn);
      }
      return this ; 
    },
    setStyle:function(prop , val){
      this.dom.style[prop] = val ;
      return this ;
    }
  };


   // window 上先注册一个全局变量 与外界产生关系
  window.$ = _$ ;
  // 写一个准备的方法
  _$.OnReady= function(fn){ 
    // 1 实例化出来_$对象 真正的注册到window上
    window.$ = function(){
      return new _$(arguments);
    };
    // 2 执行传入进来的代码
    fn();
    // 3 实现链式编程
    _$.method('addEvent',function(){
      // nothing to do
    }).method('setStyle',function(){
      // nothing to do
    });

  };

})(window); // 程序的入口 window传入作用域中


$.onReady(function(){
  var inp = $('#inp');
  //alert(inp.dom.nodeName);
  //alert($('#inp'));
  inp.addEvent('click',function(){
    alert('我被点击了!');
  }).setStyle('backgroundColor' , 'red');
});

4、使用回调函数从支持链式调用的方法获取数据

链式调用很适合于赋值器方法,但对于取值器方法,就不方便了,因为每个方法返回的都是this啊。

不过,变通的方法还是有的,那就是回调函数。

未使用回调函数时

//without callback
window.API = window.API || function(){
  var name = 'JChen';
  this.setName = function(newName){
    name = newName;
    return this;
  };
  this.getName = function(){
    return name;
  };
};
var o = new API();
console.log(o.getName());
console.log(o.setName('Haha').getName());

使用回调函数时

//with callback
window.API2 = window.API2 || function(){
  var name = 'JChen';
  this.setName = function(newName){
    name = newName;
    return this;
  };
  this.getName = function(callback){
    callback.call(this, name);
    return this;
  };
};
var o2 = new API2();
o2.getName(console.log).setName('Hehe').getName(console.log);

在使用回调函数时候callback.call(this, name)在一般情况下是没问题的,但是,这个例子偏偏用到了console.log,那么就有问题了。原因是console的this是指向console而不是winodw。

这个问题也很好解决。如下:

//with callback
window.API2 = window.API2 || function(){
  var name = 'JChen';
  this.setName = function(newName){
    name = newName;
    return this;
  };
  this.getName = function(callback){
    callback.call(this, name);
    return this;
  };
};
var o2 = new API2();
var log = function(para){
  console.log(para);
};
o2.getName(log).setName('Hehe').getName(log);

链式调用这种风格有助于简化代码的编写工作,让代码更加简洁、易读,同时也避免多次重复使用一个对象变量,希望大家可以熟练掌握。


推荐阅读
  • 本文介绍了多个关于JavaScript的书籍资源、实用工具和编程实例,涵盖从入门到进阶的各个阶段,帮助读者全面提升JavaScript编程能力。 ... [详细]
  • 本文介绍了一段使用jQuery实现的用户注册页面表单验证代码,适用于前端开发人员学习和参考。该示例结合了HTML、CSS和JavaScript,确保用户输入的数据格式正确。 ... [详细]
  • 在网站制作中随时可用的10个 HTML5 代码片段
    HTML很容易写,但创建网页时,您经常需要重复做同样的任务,如创建表单。在这篇文章中,我收集了10个超有用的HTML代码片段,有HTML5启动模板、空白图片、打电话和发短信、自动完 ... [详细]
  • 前言--页数多了以后需要指定到某一页(只做了功能,样式没有细调)html ... [详细]
  • 深入解析JMeter中的JSON提取器及其应用
    本文详细介绍了如何在JMeter中使用JSON提取器来获取和处理API响应中的数据。特别是在需要将一个接口返回的数据作为下一个接口的输入时,JSON提取器是一个非常有用的工具。 ... [详细]
  • 探讨如何使用正则表达式从类 SQL 查询语句中提取字段及其对应的值。 ... [详细]
  • 本文详细介绍了如何使用Python的re库进行正则表达式匹配,特别是针对URL中的特定参数提取。适合初学者理解和应用。 ... [详细]
  • 百度搜索结果链接提取工具 UrlGetter V1.43
    该工具专为获取百度搜索引擎的结果页面中的网址链接而设计,能够解析并转换为原始URL。通过正则表达式匹配技术,精准提取网页链接,并提供详细的使用说明和下载资源。 ... [详细]
  • 深入解析Nginx中的Location指令及其属性
    本文将详细探讨Nginx配置文件中关键的location指令,包括其三种匹配方式(精准匹配、普通匹配和正则匹配),以及如何在实际应用中灵活运用这些匹配规则。此外,还将介绍location下的重要子元素如root、alias和proxy_pass,并解释相关参数的使用方法。 ... [详细]
  • 探索电路与系统的起源与发展
    本文回顾了电路与系统的发展历程,从电的早期发现到现代电子器件的应用。文章不仅涵盖了基础理论和关键发明,还探讨了这一学科对计算机、人工智能及物联网等领域的深远影响。 ... [详细]
  • PHP 过滤器详解
    本文深入探讨了 PHP 中的过滤器机制,包括常见的 $_SERVER 变量、filter_has_var() 函数、filter_id() 函数、filter_input() 函数及其数组形式、filter_list() 函数以及 filter_var() 和其数组形式。同时,详细介绍了各种过滤器的用途和用法。 ... [详细]
  • 解决Python中 'NoneType' 对象无属性 'find_all' 错误
    本文详细探讨了在Python编程中遇到的常见错误——'NoneType'对象没有属性'find_all',并深入分析其原因及解决方案。通过理解find_all函数的工作原理和常见用法,帮助读者避免类似问题。 ... [详细]
  • Ihaveastringwithquotesaroundthepathasfollows:我在路径周围有一个带引号的字符串,如下所示:C:\ProgramFiles(x ... [详细]
  • 本文由杨勇和思远于2012年12月27日撰写,主要探讨了如何使用PHP进行网页内容抓取,特别是针对字符较多的网站。文章详细介绍了正则表达式失效的原因,并提供了优化方法,同时展示了如何抓取淘宝服饰栏、天气信息以及IP地址对应的地理位置。 ... [详细]
  • cjkjsw051,cjt521
    cjkjsw051,cjt521 ... [详细]
author-avatar
刘莉长
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有