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 相关文章推荐
jQuery拖拽div实现思路
Feb 19 Javascript
Javascript MVC框架Backbone.js详解
Sep 18 Javascript
学习Bootstrap组件之下拉菜单
Jul 28 Javascript
jquery实现加载进度条提示效果
Nov 23 Javascript
Javascript的表单验证长度
Mar 16 Javascript
JS正则匹配中文的方法示例
Jan 06 Javascript
详解vue-router2.0动态路由获取参数
Jun 14 Javascript
vue addRoutes实现动态权限路由菜单的示例
May 15 Javascript
vue2.0移动端滑动事件vue-touch的实例代码
Nov 27 Javascript
利用d3.js实现蜂巢图表带动画效果
Sep 03 Javascript
如何用threejs实现实时多边形折射
May 07 Javascript
JS的深浅复制详细
Oct 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 遍历XP文件夹下所有文件
2008/11/27 PHP
php 上传功能实例代码
2010/04/13 PHP
如何用php生成扭曲及旋转的验证码图片
2013/06/07 PHP
Laravel 5框架学习之路由、控制器和视图简介
2015/04/07 PHP
js 全兼容可高亮二级缓冲折叠菜单
2010/06/04 Javascript
JavaScript中的object转换成number或string规则介绍
2014/12/31 Javascript
FullCalendar日历插件应用之数据展现(一)
2015/12/23 Javascript
jquery插件EasyUI中form表单提交实例分享
2016/01/11 Javascript
Nodejs读取文件时相对路径的正确写法(使用fs模块)
2017/04/27 NodeJs
详解Javascript获取缓存和清除缓存API
2017/05/25 Javascript
js实现图片放大展示效果
2017/08/30 Javascript
es6中的解构赋值、扩展运算符和rest参数使用详解
2017/09/28 Javascript
解决Linux无法正常安装与卸载Node.js的方法
2018/01/19 Javascript
vue.js中$set与数组更新方法
2018/03/08 Javascript
Nodejs实现多文件夹文件同步
2018/10/17 NodeJs
vue实现移动端悬浮窗效果
2018/12/01 Javascript
Js通过AES加密后PHP用Openssl解密的方法
2019/07/12 Javascript
vue data引入本地图片的两种方式小结
2019/11/13 Javascript
JavaScript实现简单的图片切换功能(实例代码)
2020/04/10 Javascript
Python break语句详解
2014/03/11 Python
使用python实现省市三级菜单效果
2016/01/20 Python
举例讲解Python面向对象编程中类的继承
2016/06/17 Python
python使用装饰器作日志处理的方法
2019/07/11 Python
Django Rest framework权限的详细用法
2019/07/25 Python
Python线程协作threading.Condition实现过程解析
2020/03/12 Python
python 两种方法修改文件的创建时间、修改时间、访问时间
2020/09/26 Python
python如何修改文件时间属性
2021/02/05 Python
巧用CSS3的calc()宽度计算做响应模式布局的方法
2018/03/22 HTML / CSS
学校对教师的评语
2014/04/28 职场文书
优秀教师事迹材料
2014/12/15 职场文书
幼儿园小班工作总结2015
2015/04/25 职场文书
二胎满月酒致辞
2015/07/29 职场文书
2016幼儿园中班开学寄语
2015/12/03 职场文书
matplotlib画混淆矩阵与正确率曲线的实例代码
2021/06/01 Python
Redis 持久化 RDB 与 AOF的执行过程
2021/11/07 Redis
讲解Python实例练习逆序输出字符串
2022/05/06 Python