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 相关文章推荐
JAVASCRIPT HashTable
Jan 22 Javascript
JavaScript实现的一个倒计时的类
Mar 12 Javascript
在Node.js中使用HTTP上传文件的方法
Jun 23 Javascript
js实现显示当前状态的导航效果代码
Aug 28 Javascript
jQuery的选择器中的通配符[id^='code']或[name^='code']及jquery选择器总结
Dec 24 Javascript
jQuery中attr()与prop()函数用法实例详解(附用法区别)
Dec 29 Javascript
jQuery实现的导航下拉菜单效果示例
Sep 05 Javascript
Node.js与MySQL交互操作及其注意事项
Oct 05 Javascript
微信小程序开发背景图显示功能
Aug 08 Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 Javascript
教你完全理解ReentrantLock重入锁
Jun 03 Javascript
JS Math对象与Math方法实例小结
Jul 05 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
PHP中strlen()和mb_strlen()的区别浅析
2014/06/19 PHP
php猴子选大王问题解决方法
2015/05/12 PHP
php注册系统和使用Xajax即时验证用户名是否被占用
2017/08/31 PHP
ThinkPHP5框架缓存查询操作分析
2018/05/30 PHP
Tab切换组件(选项卡功能)实例代码
2013/11/21 Javascript
深入理解JavaScript系列(33):设计模式之策略模式详解
2015/03/03 Javascript
JavaScript中函数(Function)的apply与call理解
2015/07/08 Javascript
javascript实现拖动元素交换位置
2015/11/29 Javascript
javascript字符串函数汇总
2015/12/06 Javascript
BootStrap框架个人总结(bootstrap框架、导航条、下拉菜单、轮播广告carousel、栅格系统布局、标签页tabs、模态框、菜单定位)
2016/12/01 Javascript
使用JSON格式提交数据到服务端的实例代码
2018/04/01 Javascript
javaScript强制保留两位小数的输入数校验和小数保留问题
2018/05/09 Javascript
JS实现匀速与减速缓慢运动的动画效果封装示例
2018/08/27 Javascript
Node.js console控制台简单用法分析
2019/01/04 Javascript
如何为你的JavaScript代码日志着色详解
2019/04/08 Javascript
nuxt踩坑之Vuex状态树的模块方式使用详解
2019/09/06 Javascript
JS通过识别id、value值对checkbox设置选中状态
2020/02/19 Javascript
微信小程序文章详情功能完整实例
2020/06/03 Javascript
微信小程序实现选择地址省市区三级联动
2020/06/21 Javascript
iview实现动态表单和自定义验证时间段重叠
2021/01/10 Javascript
[54:57]DOTA2-DPC中国联赛定级赛 Aster vs DLG BO3第二场 1月8日
2021/03/11 DOTA
Python内置函数之filter map reduce介绍
2014/11/30 Python
python psutil库安装教程
2018/03/19 Python
基于MTCNN/TensorFlow实现人脸检测
2018/05/24 Python
详解配置Django的Celery异步之路踩坑
2018/11/25 Python
python 用下标截取字符串的实例
2018/12/25 Python
解决Python中定时任务线程无法自动退出的问题
2019/02/18 Python
Python对列表的操作知识点详解
2019/08/20 Python
pytorch中torch.max和Tensor.view函数用法详解
2020/01/03 Python
jupyter notebook 参数传递给shell命令行实例
2020/04/10 Python
520使用Python实现“我爱你”表白
2020/05/20 Python
python 图像插值 最近邻、双线性、双三次实例
2020/07/05 Python
python em算法的实现
2020/10/03 Python
HTML5中5个简单实用的API
2014/04/28 HTML / CSS
审计工作个人的自我评价
2013/12/25 职场文书
食品厂厂长岗位职责
2014/01/30 职场文书