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基础 函数“重载” 详细介绍
Oct 25 Javascript
Get中文乱码IE浏览器Get中文乱码解决方案
Dec 26 Javascript
php的文件上传入门教程(实例讲解)
Apr 10 Javascript
教你如何自定义百度分享插件以及bshare分享插件的分享按钮
Jun 20 Javascript
封装属于自己的JS组件
Jan 27 Javascript
JavaScript数据绑定实现一个简单的 MVVM 库
Apr 08 Javascript
jQuery元素属性操作实例(设置、获取及删除元素属性)
Sep 08 Javascript
前端分页功能的实现以及原理(jQuery)
Jan 22 Javascript
JavaScript同源策略和跨域访问实例详解
Apr 03 Javascript
浅谈JS的原型和继承
May 08 Javascript
Webpack3+React16代码分割的实现
Mar 03 Javascript
JavaScript 中for/of,for/in 的详细介绍
Nov 17 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 什么是PEAR?(第三篇)
2009/03/19 PHP
php获取当月最后一天函数分享
2015/02/02 PHP
PHP 5.3和PHP 5.4出现FastCGI Error解决方法
2015/02/12 PHP
PHP中常用的三种设计模式详解【单例模式、工厂模式、观察者模式】
2019/06/14 PHP
PHP实现一个限制实例化次数的类示例
2019/09/16 PHP
js/jquery获取浏览器窗口可视区域高度和宽度以及滚动条高度实现代码
2012/12/17 Javascript
不使用浏览器运行javascript代码的方法
2013/07/24 Javascript
jquery easyui 对于开始时间小于结束时间的判断示例
2014/03/22 Javascript
jquery中post方法用法实例
2014/10/21 Javascript
使用AngularJS编写较为优美的JavaScript代码指南
2015/06/19 Javascript
Javascript的表单验证-揭开正则表达式的面纱
2016/03/18 Javascript
js选择器全面解析
2016/06/27 Javascript
jQuery+CSS实现简单切换菜单示例
2016/07/27 Javascript
原生JS实现网络彩票投注效果
2016/09/25 Javascript
js 性能优化之算法和流程控制
2017/02/15 Javascript
JS中利用localStorage防止页面动态添加数据刷新后数据丢失
2017/03/10 Javascript
基于angular-utils-ui-breadcrumbs使用心得(分享)
2017/11/03 Javascript
如何使用electron-builder及electron-updater给项目配置自动更新
2018/12/24 Javascript
vue-video-player实现实时视频播放方式(监控设备-rtmp流)
2020/08/10 Javascript
python append、extend与insert的区别
2016/10/13 Python
对Python 文件夹遍历和文件查找的实例讲解
2018/04/26 Python
Python实现聊天机器人的示例代码
2018/07/09 Python
Python实现的建造者模式示例
2018/08/06 Python
Python 利用切片从列表中取出一部分使用的方法
2019/02/01 Python
对python 通过ssh访问数据库的实例详解
2019/02/19 Python
python通过对字典的排序,对json字段进行排序的实例
2020/02/27 Python
CSS改变网页中鼠标选中文字背景颜色例子
2014/04/23 HTML / CSS
英国时尚首饰品牌:Missoma
2020/06/29 全球购物
个人现实表现材料
2014/02/04 职场文书
爱情寄语大全
2014/04/09 职场文书
财务助理岗位职责范本
2014/10/09 职场文书
六年级小学生评语
2014/12/26 职场文书
考勤制度通知
2015/04/25 职场文书
结婚主持人致辞
2015/07/28 职场文书
2015年国庆节标语大全
2015/07/30 职场文书
美德少年主要事迹材料
2015/11/04 职场文书