Javasript设计模式之链式调用详解


Posted in Javascript onApril 26, 2018

本文实例为大家分享了js设计模式之链式调用的具体代码,供大家参考,具体内容如下

写过jquery的可能都知道,jquery里面可以很方便的使用以下代码:

// 不使用链式调用
const element = $(ele);
element.addClass('red');
element.removeClass('green');
element.show();

// 链式调用
$(ele)
 .addClass('red')
 .removeClass('green')
 .show();

而jquery这种调用方式就是链式调用。我们可以从上述代码看出来,如果不使用链式调用的话,那么我们会增加很多重复的代码,而且特别冗余。而通过链式调用,我们可以节省很多代码,并且代码看起来更加优雅和整洁。那么,接下来,我们来讨论下如何实现一个支持链式调用的库。

了解过原型链的人都知道,由构造函数生成的实例都可以访问其原型对象的属性和方法,因此,我们让定义在原型对象的方法最后都返回this(调用该方法的实例),就可以对原型方法进行链式调用。

// 通过立即执行函数,声明了一个_$函数,并且将一个$函数挂载到window上,并且每次调用$()的时候,返回的其实是个_$实例,由于原型对象方法里,执行最后都会返回一个this,因此就可以执行链式调用。
(function () {
 // 构造函数
 function _$(selector) {
  // ...
 }

 _$.prototype = {
  addClass: function (className) {
   // ...
   return this;
  },
  removeClass: function (className) {
   // ...
   return this;
  },
  show: function () {
   // ...
   return this;
  }
 };

 _$.prototype.constructor = _$;

 // 每次调用$()的时候,返回的其实是个_$实例
 window.$ = function () {
  return new _$(arguments);
 }
})();

// 通过这种方式,我们就可以直接使用$的链式调用
$(ele)
 .addClass('red')
 .removeClass('green')
 .show();

当然,上述代码其实可以进行优化一下,因为假设你引入的库里,已经有人定义了$函数,那么就会面临着命名冲突的问题。所以,我们可以为其增加一个安装器

(function () {
 // 构造函数
 function _$(selector) {
  // ...
 }

 _$.prototype = {
  addClass: function (className) {
   // ...
   return this;
  },
  removeClass: function (className) {
   // ...
   return this;
  },
  show: function () {
   // ...
   return this;
  }
 };

 _$.prototype.constructor = _$;

 // 增加一个安装器
 window.installHelper = function (scope, interface) {
  scope[interface] = function () {
   return new _$(arguments);
  }
 }
})();

// 而用户就可以这样使用它来自定义挂载对象以及其命名
installHelper(window, '$');

$(ele).show();

当然,有时候链式调用并不是一个好的主意。链式调用适用于赋值器方法,但是对于取值器方法的话,就不是很友好。因为我们有时候是想要方法返回一些数据,而不是返回一个this。对于这种情况的话,主要有两种解决方法,一种是对于取值器方法就不返回this,直接返回数据。而另一种方法呢,则是通过回调方法来处理数据:

// 第一种方法,当遇到取值器,则直接返回数据
(function () {
 // 构造函数
 function _$(selector) {
  this.ele = document.querySelector(selector);
  // ...
 }

 _$.prototype = {
  addClass: function (className) {
   // ...
   return this;
  },
  // 取值器
  getClass: function () {
   // ...
   return this.ele.className;
  }
 };

 _$.prototype.constructor = _$;
})();

// 第二种方式,通过回调的方式来处理数据
(function () {
 // 构造函数
 function _$(selector) {
  this.ele = document.querySelector(selector);
  // ...
 }

 _$.prototype = {
  addClass: function (className) {
   // ...
   return this;
  },
  getClass: function (cb) {
   // ...
   cb.call(this, this.ele.className);
   return this;
  }
 };

 _$.prototype.constructor = _$;
})();

通过链式调用,我们可以简化我们的代码,让代码更加简洁易读。而我们只需要让类所有的方法都返回this值,就可以让该类变化一个支持方法链式调用的类。而如果要让取值器方法也支持链式调用,就可以在取值器里使用回调的方式来解决这个问题。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
Jquery 学习笔记(一)
Oct 13 Javascript
Asp.net下使用Jquery Ajax传送和接收DataTable的代码
Sep 12 Javascript
node.js正则表达式获取网页中所有链接的代码实例
Jun 03 Javascript
JavaScript中的数组操作介绍
Dec 30 Javascript
JavaScript返回上一页的三种方法及区别介绍
Jul 04 Javascript
jQuery中借助deferred来请求及判断AJAX加载的实例讲解
May 24 Javascript
源码分析Vue.js的监听实现教程
Apr 23 Javascript
jQuery EasyUI结合zTree树形结构制作web页面
Sep 01 jQuery
深入理解Vue官方文档梳理之全局API
Nov 22 Javascript
Vue刷新修改页面中数据的方法
Sep 16 Javascript
PM2自动部署代码步骤流程总结
Dec 10 Javascript
Node在Controller层进行数据校验的过程详解
Aug 28 Javascript
在vue-cli搭建的项目中增加后台mock接口的方法
Apr 26 #Javascript
vue 做移动端微信公众号采坑经验记录
Apr 26 #Javascript
jQuery length 和 size()区别总结
Apr 26 #jQuery
Hexo已经看腻了,来手把手教你使用VuePress搭建个人博客
Apr 26 #Javascript
详解Vue项目编译后部署在非网站根目录的解决方案
Apr 26 #Javascript
vue如何判断dom的class
Apr 26 #Javascript
vue 中filter的多种用法
Apr 26 #Javascript
You might like
IIS6.0 开启Gzip方法及PHP Gzip函数分享
2014/06/08 PHP
phpstorm编辑器乱码问题解决
2014/12/01 PHP
PHP微信红包API接口
2015/12/05 PHP
Linux+Nginx+MySQL下配置论坛程序Discuz的基本教程
2015/12/23 PHP
php中array_column函数简单实现方法
2016/07/11 PHP
ThinkPHP 模板引擎使用详解
2017/05/07 PHP
PHP lcfirst()函数定义与用法
2019/03/08 PHP
在Laravel中使用GuzzleHttp调用第三方服务的API接口代码
2019/10/15 PHP
Prototype使用指南之hash.js
2007/01/10 Javascript
用javascript自动显示最后更新时间
2007/03/15 Javascript
CSS常用网站布局实例
2008/04/03 Javascript
javascript 实现子父窗体互相传值的简单实例
2014/02/17 Javascript
用javascript关闭本窗口不弹出询问框的方法
2014/09/12 Javascript
举例详解Python中smtplib模块处理电子邮件的使用
2015/06/24 Javascript
微信小程序 WXML、WXSS 和JS介绍及详解
2016/10/08 Javascript
vue2组件实现懒加载浅析
2017/03/29 Javascript
微信小程序 action-sheet 反馈上拉菜单简单实例
2017/05/11 Javascript
JS中Safari浏览器中的Date
2017/07/17 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
mpvue全局引入sass文件的方法步骤
2019/03/06 Javascript
基于JS实现计算24点算法代码实例解析
2020/07/23 Javascript
vue-cli3项目打包后自动化部署到服务器的方法
2020/09/16 Javascript
如何使用RoughViz可视化Vue.js中的草绘图表
2021/01/30 Vue.js
[44:26]DOTA2上海特级锦标赛主赛事日 - 2 胜者组第一轮#4EG VS Fnatic第二局
2016/03/03 DOTA
Python用zip函数同时遍历多个迭代器示例详解
2016/11/14 Python
浅谈用Python实现一个大数据搜索引擎
2017/11/28 Python
django上传图片并生成缩略图方法示例
2017/12/11 Python
Tornado高并发处理方法实例代码
2018/01/15 Python
python实现猜数字游戏
2020/03/25 Python
Python Socket TCP双端聊天功能实现过程详解
2020/06/15 Python
iphoneX 适配客户端H5页面的方法教程
2017/12/08 HTML / CSS
幼儿园教师辞职信
2014/01/18 职场文书
面试通知短信
2015/04/20 职场文书
给校长的建议书作文400字
2015/09/14 职场文书
Matlab求解数组中的最大值及它所在的具体位置
2021/04/16 Python
使用Nginx的访问日志统计PV与UV
2022/05/06 Servers