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中的Location地址对象
Jan 16 Javascript
基于jquery.Jcrop的头像编辑器
Mar 01 Javascript
javascript数组操作总结和属性、方法介绍
Apr 05 Javascript
js实现点击链接后窗口缩小并居中的方法
Mar 02 Javascript
javascript常用方法总结
May 14 Javascript
浅谈JavaScript 函数参数传递到底是值传递还是引用传递
Aug 23 Javascript
手机图片预览插件photoswipe.js使用总结
Aug 25 Javascript
vue.js实现备忘录功能的方法
Jul 10 Javascript
security.js实现的RSA加密功能示例
Jun 06 Javascript
微信小程序实现页面下拉刷新和上拉加载功能详解
Dec 03 Javascript
vue实现滑动切换效果(仅在手机模式下可用)
Jun 29 Javascript
原生JavaScript实现随机点名表
Jan 14 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安全开发库中文详细介绍
2015/03/22 PHP
yii框架无限极分类的实现方法
2017/04/08 PHP
jQuery Animation实现CSS3动画示例介绍
2013/08/14 Javascript
通过JS来判断页面控件是否获取焦点
2014/01/03 Javascript
jQuery DOM删除节点操作指南
2015/03/03 Javascript
JSONP之我见
2015/03/24 Javascript
浅析JavaScript中的变量复制、参数传递和作用域链
2016/01/13 Javascript
几句话带你理解JS中的this、闭包、原型链
2016/09/26 Javascript
bootstrapValidator自定验证方法写法
2016/12/01 Javascript
javascript兼容性(实例讲解)
2017/08/15 Javascript
JavaScript编写的网页小游戏,很给力
2017/08/18 Javascript
原生JS实现网页手机音乐播放器 歌词同步播放的示例
2018/02/02 Javascript
浅谈如何使用webpack构建多页面应用
2018/05/30 Javascript
vue+express 构建后台管理系统的示例代码
2018/07/19 Javascript
微信小程序事件 bindtap bindinput代码实例
2019/08/26 Javascript
如何换个角度使用VUE过滤器详解
2019/09/11 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
2020/07/26 Javascript
[01:28:31]《加油DOTA》真人秀 第五期
2014/09/01 DOTA
Python判断文本中消息重复次数的方法
2016/04/27 Python
Python 调用Java实例详解
2017/06/02 Python
Python实现输出某区间范围内全部素数的方法
2018/05/02 Python
一行Python代码过滤标点符号等特殊字符
2019/08/12 Python
Jupyter notebook 启动闪退问题的解决
2020/04/13 Python
django model 条件过滤 queryset.filter(**condtions)用法详解
2020/05/20 Python
Scrapy-Redis之RedisSpider与RedisCrawlSpider详解
2020/11/18 Python
Python爬虫设置Cookie解决网站拦截并爬取蚂蚁短租的问题
2021/02/22 Python
解决TensorFlow训练模型及保存数量限制的问题
2021/03/03 Python
Maison Lab荷兰:名牌Outlet购物
2018/08/10 全球购物
外贸业务员求职自荐信分享
2013/09/21 职场文书
大学生就业策划书范文
2014/04/04 职场文书
莫言诺贝尔获奖演讲稿
2014/05/21 职场文书
节约用电标语
2014/06/17 职场文书
领导干部遵守党的政治纪律情况思想汇报
2014/09/14 职场文书
实习计划书范文
2015/01/16 职场文书
全面盘点MySQL中的那些重要日志文件
2021/11/27 MySQL
SQLServer权限之只开启创建表权限
2022/04/12 SQL Server