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 相关文章推荐
用javascript实现画板的代码
Sep 05 Javascript
传智播客学习之JavaScript基础篇
Nov 13 Javascript
Jquery 插件学习实例1 插件制作说明与tableUI优化
Apr 02 Javascript
javascript判断用户浏览器插件安装情况的代码
Jan 01 Javascript
JavaScript中的this实例分析
Apr 28 Javascript
JS交换变量的方法
Jan 21 Javascript
学习JavaScript设计模式之代理模式
Jan 12 Javascript
利用Javascript仿Excel的数据透视分析功能
Sep 07 Javascript
微信小程序左右滑动切换页面详解及实例代码
Feb 28 Javascript
jQuery在header中设置请求信息的方法
Mar 06 Javascript
基于JQuery的购物车添加删除以及结算功能示例
Mar 08 Javascript
微信小程序开发图片拖拽实例详解
May 05 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中的比较运算符详解
2013/10/28 PHP
PHP+APACHE实现网址伪静态
2015/02/22 PHP
CodeIgniter配置之routes.php用法实例分析
2016/01/19 PHP
PHP入门教程之图像处理技巧分析
2016/09/11 PHP
一个用javascript写的select支持上下键、首字母筛选以及回车取值的功能
2009/09/09 Javascript
js实现拖拽效果
2015/02/12 Javascript
javascript事件委托的方式绑定详解
2015/06/10 Javascript
JS基于Ajax实现的网页Loading效果代码
2015/10/27 Javascript
JS 对java返回的json格式的数据处理方法
2016/12/05 Javascript
利用纯JS实现像素逐渐显示的方法示例
2017/08/14 Javascript
200行代码实现blockchain 区块链实例详解
2018/03/14 Javascript
Node.js连接Sql Server 2008及数据层封装详解
2018/08/27 Javascript
Vue中的methods、watch、computed的区别
2018/11/26 Javascript
vue中动态select的使用方法示例
2019/10/28 Javascript
javascript实现视频弹幕效果(两个版本)
2019/11/28 Javascript
JavaScript canvas实现跟随鼠标事件
2020/02/10 Javascript
angula中使用iframe点击后不执行变更检测的问题
2020/05/10 Javascript
vant实现购物车功能
2020/06/29 Javascript
Angular短信模板校验代码
2020/09/23 Javascript
[03:45]Newbee战队出征西雅图 决战2016国际邀请赛
2016/08/02 DOTA
python图片验证码生成代码
2016/07/02 Python
python 连接sqlite及简单操作
2017/06/30 Python
对numpy中shape的深入理解
2018/06/15 Python
Python根据成绩分析系统浅析
2019/02/11 Python
python学习开发mock接口
2019/04/28 Python
python3.6+django2.0+mysql搭建网站过程详解
2019/07/24 Python
python英语单词测试小程序代码实例
2019/09/09 Python
Python3如何实现Win10桌面自动切换
2020/08/11 Python
赫里福德的一家乡村零售商店:Philip Morris & Son
2017/06/25 全球购物
介绍一下Ruby的多线程处理
2013/02/01 面试题
大学生收银员求职信分享
2014/01/02 职场文书
学校安全管理责任书
2014/07/23 职场文书
购房委托书范本
2014/09/18 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
中学生逃课检讨书
2015/02/17 职场文书
python flask开发的简单基金查询工具
2021/06/02 Python