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 相关文章推荐
打开超链需要“确认”对话框的方法
Mar 08 Javascript
javascript之大字符串的连接的StringBuffer 类
May 08 Javascript
Convert Seconds To Hours
Jun 16 Javascript
JavaScript中的prototype和constructor简明总结
Apr 05 Javascript
数据分析软件之FineReport教程:[5]参数界面JS(全)
Aug 13 Javascript
JQuery插件Marquee.js实现无缝滚动效果
Apr 26 Javascript
jQuery CSS3自定义美化Checkbox实现代码
May 12 Javascript
JS中使用DOM来控制HTML元素
Jul 31 Javascript
从零开始做一个pagination分页组件
Mar 15 Javascript
web.js.字符串与正则表达式操作
May 13 Javascript
深入浅析angular和vue还有jquery的区别
Aug 13 jQuery
使用 JavaScript 制作页面效果
Apr 21 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
网络资源
2006/10/09 PHP
基于flush()不能按顺序输出时的解决办法
2013/06/29 PHP
mac系统下为 php 添加 pcntl 扩展
2016/08/28 PHP
php代码调试利器firephp安装与使用方法分析
2018/08/21 PHP
用脚本调用样式的几种方法
2006/12/09 Javascript
jquery text()要注意啦
2009/10/30 Javascript
Jquery Ajax学习实例7 Ajax所有过程事件分析示例
2010/03/23 Javascript
解析ScrollPic在ie8下只滚动一遍,然后变为空白 ie6,ie7,chrome,firefox正常
2013/06/26 Javascript
ajax跨域调用webservice的实现代码
2016/05/09 Javascript
JS获取元素多层嵌套思路详解
2016/05/16 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
2016/07/01 Javascript
简单理解vue中el、template、replace元素
2016/10/27 Javascript
js基础之DOM中元素对象的属性方法详解
2016/10/28 Javascript
vue.js学习之递归组件
2016/12/13 Javascript
JavaScript中定义对象原型的两种使用方法
2016/12/15 Javascript
layer弹出层中H5播放器全屏出错的解决方法
2017/02/21 Javascript
React操作真实DOM实现动态吸底部的示例
2017/10/23 Javascript
详解js创建对象的几种方法及继承
2019/04/12 Javascript
Windows上node.js的多版本管理工具用法实例分析
2019/11/06 Javascript
JS图片懒加载的优点及实现原理
2020/01/10 Javascript
python格式化字符串实例总结
2014/09/28 Python
python实现根据窗口标题调用窗口的方法
2015/03/13 Python
Python高级特性切片(Slice)操作详解
2018/09/27 Python
Appium Python自动化测试之环境搭建的步骤
2019/01/23 Python
PyCharm设置Ipython交互环境和宏快捷键进行数据分析图文详解
2020/04/23 Python
python uuid生成唯一id或str的最简单案例
2021/01/13 Python
用纯CSS3实现网页中常见的小箭头
2017/10/16 HTML / CSS
原生canvas制作画图小工具的踩坑和爬坑
2020/06/09 HTML / CSS
生物专业个人自荐信范文
2013/11/29 职场文书
电子信息专业自荐书
2014/02/04 职场文书
贷款委托书
2014/08/01 职场文书
龙潭大峡谷导游词
2015/02/10 职场文书
公司借条范本
2015/05/25 职场文书
2019销售早会主持词
2019/06/27 职场文书
nginx网站服务如何配置防盗链(推荐)
2021/03/31 Servers
微信小程序中使用vant框架的具体步骤
2022/02/18 Javascript