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实现网页图片等比例缩放实现代码及调用方式
Feb 25 Javascript
jQuery当鼠标悬停时放大图片的效果实例
Jul 03 Javascript
基于javascript实现动态显示当前系统时间
Jan 28 Javascript
ES6实现的遍历目录函数示例
Apr 07 Javascript
详解vue2.0的Element UI的表格table列时间戳格式化
Jun 13 Javascript
vue填坑之webpack run build 静态资源找不到的解决方法
Sep 03 Javascript
使用validate.js实现表单数据提交前的验证方法
Sep 04 Javascript
使用iView Upload 组件实现手动上传图片的示例代码
Oct 01 Javascript
vue-router权限控制(简单方式)
Oct 29 Javascript
js实现图片上传即时显示效果
Sep 30 Javascript
vue data引入本地图片的两种方式小结
Nov 13 Javascript
解决vue+ element ui 表单验证有值但验证失败问题
Jan 16 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脚本的10个技巧(6)
2006/10/09 PHP
phpmyadmin3 安装配置图解教程
2012/03/29 PHP
php使用ZipArchive提示Fatal error: Class ZipArchive not found in的解决方法
2014/11/04 PHP
PHP多种序列化/反序列化的方法详解
2017/06/23 PHP
javascript上传图片前预览图片兼容大多数浏览器
2013/10/25 Javascript
在JS中解析HTML字符串示例代码
2014/04/16 Javascript
Javascript基于AJAX回调函数传递参数实例分析
2015/12/15 Javascript
jQuery+PHP+MySQL实现无限级联下拉框效果
2016/02/19 Javascript
jQuery中on绑定事件后引发的事件冒泡问题如何解决
2016/05/25 Javascript
vue.js指令v-for使用及索引获取
2016/11/03 Javascript
Angular directive递归实现目录树结构代码实例
2017/05/05 Javascript
vue.js实现刷新当前页面的方法教程
2017/07/05 Javascript
iscroll动态加载数据完美解决方法
2017/07/18 Javascript
用JS实现简单的登录验证功能
2017/07/28 Javascript
vue的全局变量和全局拦截请求器的示例代码
2018/09/13 Javascript
深入理解webpack process.env.NODE_ENV配置
2020/02/23 Javascript
查找Vue中下标的操作(some和findindex)
2020/08/12 Javascript
Pyhton中防止SQL注入的方法
2015/02/05 Python
用Python的Django框架来制作一个RSS阅读器
2015/07/22 Python
Python基于回溯法子集树模板实现图的遍历功能示例
2017/09/05 Python
TensorFlow如何实现反向传播
2018/02/06 Python
python 通过xml获取测试节点和属性的实例
2018/03/31 Python
Python使用Pandas库实现MySQL数据库的读写
2019/07/06 Python
超简单的Python HTTP服务
2019/07/22 Python
django2.2安装错误最全的解决方案(小结)
2019/09/24 Python
Matplotlib自定义坐标轴刻度的实现示例
2020/06/18 Python
python多线程和多进程关系详解
2020/12/14 Python
CSS3 实现雷达扫描图的示例代码
2020/09/21 HTML / CSS
大学学习生活感言
2014/01/18 职场文书
内刊编辑求职自荐书范文
2014/02/19 职场文书
土木工程师职业规划范文
2014/03/07 职场文书
园林设计专业毕业生求职信
2014/03/23 职场文书
网吧员工管理制度
2015/08/05 职场文书
中秋节主题班会
2015/08/14 职场文书
大学生党员暑假实践(活动总结)
2019/08/21 职场文书
CPU不支持Windows11系统怎么办
2021/11/21 数码科技