JavaScript链式调用实例浅析


Posted in Javascript onDecember 19, 2018

本文实例分析了JavaScript链式调用。分享给大家供大家参考,具体如下:

$函数你已经很熟悉了。它通常返回一个html元素或一个html元素的集合,如下:

function$(){
  var elements = [];
  for(vari=0,len=arguments.length;i<len;++i){
     var element = arguments[i];
     if(typeof element ===”string”){
       element = document.getElementById(element);
     }
     if(arguments.length==1){
        return element;
      }
      elements.push(element);
  }
   return elements;
}

但是,如果把这个函数改造为一个构造器,把那些元素作为数组保存在一个实例属性中,并让所有定义在构造器函数的prototype属性所指对象中的方法都返回用以调用方法的那个实例的引用,那么它就具有了链式调用的能力。我首先需要把这个$函数改为一个工厂方法,它负责创建支持链式调用的对象。这个函数应该能接受元素数组形式的参数,以便我们能够使用与原来一样的公用接口。

(function(){
  //use private class
   function _$(els){
    this.elements = [];
     for(vari=0,len=els.length;i<len;i++){
      var element = els[i];
       if(typeof element ===”string”){
        element = document.getElementById(element);
       }
       this.elements.push(element)
     }
   }
    //The public interface remains the same.
    window.$ = function(){
       return new _$(arguments);
    }
})();

由于所有对象都会继承其原型对象的属性和方法,所以我们可以让定义在原型对象中的那几个方法都返回用以调用方法的实例对象的引用,这样就可以对那些方法进行链式调用。想好这一点,我们现在就动手在_$这个私用构造函数的prototype对象中添加方法,以便实现链式调用

(function(){
  //use private class
  function _$(els){
    //..省略之前上面的代码
  }
  _$.prototype = {
    each:function(fn){
      for(var i=0,len=this.elements.length;i<len;i++){
        fn.call(this,this.elements[i]);
      }
      return this;
    },
    show:function(prop,val){
      var that = this;
      this.each(function(el){
        that.setStyle("display”,”block");
      });
      return this;
    },
    addEvent:function(type,fn){
      var add = function(el){
        if(window.addEventListener){
         el.addEventListener(type,fn,false);
        }else if(window.attachEvent){
         el.attachEvent("on"+type,fn);
        }
      };
      this.each(function(el){
        add(el);
      });
      return this;
    }
  };
  //The public interface remains the same.
  window.$ = function(){
    return new _$(arguments);
  }
})();

但是如果某个库或者框架已经定义了一个$函数,那么我们的这个库会将其改写,有个简单的办法是在源码中为$函数另去一个名字。但是如果你是从一个现有的库获得的源码,那么每次代码库获取更新的版本后 你都得重新改名字,因此这个方案并不是很好。好的解决办法就是像下面一样添加一个安装器:

window.installHelper = function(scope, interface) {
  scope[interface] = function() {
   return new _$(arguments);
  }
 };

用户可以这样去使用:

installHelper(window, '$');
$('example').show();

下面是一个更复杂的例子,它展示了如何把这种功能添加到一个事先定义好的命名对象中:

// Define a namespace without overwriting it if it already exists.
window.com = window.com || {};
com.example = com.example || {};
com.example.util = com.example.util || {};
installHelper(com.example.util, 'get');
(function() {
 var get = com.example.util.get;
 get('example').addEvent('click', function(e) {
  get(this).addClass('hello');
 });
})();

有时候把方法连起来并不是一个好主意。链式调用很适合于赋值器方法,但对于取值器的方法,你可能会希望他们返回你要的数据而不是返回this。不过,如果你把链式调用作为首要目标,希望所有方法的使用方式保持一致的话,那么变通的方法还是有的:你可以利用回调技术来返回所要的数据下面有两个例子:其中API类使用了普通的取值器(它中断了调用链),而API2类则使用了回调方法:

// Accessor without function callbacks: returning requested data in accessors.
window.API = window.API || {};
API.prototype = function() {
 var name = 'Hello world';
 // Privileged mutator method.
 setName: function(newName) {
  name = newName;
  return this;
 },
 // Privileged accessor method.
 getName: function() {
  return name;
 }
}();
// Implementation code.
var o = new API;
console.log(o.getName()); // Displays 'Hello world'.
console.log(o.setName('Meow').getName()); // Displays 'Meow'.
// Accessor with function callbacks.
window.API2 = window.API2 || {};
API2.prototype = function() {
 var name = 'Hello world';
 // Privileged mutator method.
 setName: function(newName) {
  name = newName;
  return this;
 },
 // Privileged accessor method.
 //通过把函数作为参数传入
 getName: function(callback) {
  callback.call(this, name);
  return this;
 }
}();
// Implementation code.
var o2 = new API2;
o2.getName(console.log).setName('Meow').getName(console.log);
// Displays 'Hello world' and then 'Meow'.

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
js innerHTML 的一些问题的解决方法
Jun 22 Javascript
DOM下的节点属性和操作小结
May 14 Javascript
jquery交替变换颜色的三种方法 实例代码
Nov 19 Javascript
js 模式窗口(模式对话框和非模式对话框)的使用介绍
Jul 17 Javascript
javascript解析json实例详解
Nov 05 Javascript
javascript无刷新评论实现方法
May 13 Javascript
Clipboard.js 无需Flash的JavaScript复制粘贴库
Oct 02 Javascript
AngularJS表格样式简单设置方法示例
Mar 03 Javascript
JS实现基于Sketch.js模拟成群游动的蝌蚪运动动画效果【附demo源码下载】
Aug 18 Javascript
vue 指令之气泡提示效果的实现代码
Oct 18 Javascript
详解VS Code使用之Vue工程配置format代码格式化
Mar 20 Javascript
Vue axios与Go Frame后端框架的Options请求跨域问题详解
Mar 03 Javascript
浅谈vue后台管理系统权限控制思考与实践
Dec 19 #Javascript
如何为vue的项目添加单元测试
Dec 19 #Javascript
浅谈Angular7 项目开发总结
Dec 19 #Javascript
mockjs+vue页面直接展示数据的方法
Dec 19 #Javascript
vue项目搭建以及全家桶的使用详细教程(小结)
Dec 19 #Javascript
vue使用Google地图的实现示例代码
Dec 19 #Javascript
JS实现获取自定义属性data值的方法示例
Dec 19 #Javascript
You might like
PHP中创建图像并绘制文字的例子
2014/11/19 PHP
php计算两个日期相差天数的方法
2015/03/14 PHP
常用的php图片处理类(水印、等比缩放、固定高宽)分享
2015/06/19 PHP
Display SQL Server Version Information
2007/06/21 Javascript
JS target与currentTarget区别说明
2011/08/28 Javascript
jQuery调用RESTful WCF示例代码(GET方法/POST方法)
2014/01/26 Javascript
javascript控制台详解
2015/06/25 Javascript
JS实现完全语义化的网页选项卡效果代码
2015/09/15 Javascript
使用JQuery实现的分页插件分享
2015/11/05 Javascript
JavaScript中获取纯正的undefined的方法
2016/03/06 Javascript
JSON 的正确用法探讨:Pyhong、MongoDB、JavaScript与Ajax
2016/05/15 Javascript
移动端脚本框架Hammer.js
2016/12/15 Javascript
简单学习5种处理Vue.js异常的方法
2019/06/17 Javascript
layui 中select下拉change事件失效的解决方法
2019/09/20 Javascript
jQuery冲突问题解决方法
2021/01/19 jQuery
使用python Django做网页
2013/11/04 Python
wxpython学习笔记(推荐查看)
2014/06/09 Python
Python中的filter()函数的用法
2015/04/27 Python
Python中几个比较常见的名词解释
2015/07/04 Python
Python针对给定列表中元素进行翻转操作的方法分析
2018/04/27 Python
python使用turtle绘制分形树
2018/06/22 Python
Python通过for循环理解迭代器和生成器实例详解
2019/02/16 Python
Python日期时间Time模块实例详解
2019/04/15 Python
Numpy的简单用法小结
2019/08/28 Python
Python编程快速上手——选择性拷贝操作案例分析
2020/02/28 Python
matplotlib.pyplot.matshow 矩阵可视化实例
2020/06/16 Python
Pytorch之扩充tensor的操作
2021/03/04 Python
css3选择器基本介绍
2014/12/15 HTML / CSS
css3弹性盒子flex实现三栏布局的实现
2020/11/12 HTML / CSS
State Cashmere官网:半零售价可持续蒙古羊绒
2020/02/26 全球购物
自我评价是什么
2014/01/04 职场文书
中学生期中自我鉴定
2014/04/20 职场文书
MySQL8.0.24版本Release Note的一些改进点
2021/04/22 MySQL
Python办公自动化之Excel(中)
2021/05/24 Python
7个关于Python的经典基础案例
2021/11/07 Python
nginx sticky实现基于cookie负载均衡示例详解
2022/12/24 Servers