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 相关文章推荐
js 蒙版进度条(结合图片)
Mar 10 Javascript
jquery 圆形旋转图片滚动切换效果
Jan 19 Javascript
循环 vs 递归浅谈
Feb 28 Javascript
批量修改标签css样式以input标签为例
Jul 31 Javascript
jQuery中wrapInner()方法用法实例
Jan 16 Javascript
Javascript缓存API
Jun 14 Javascript
纯css下拉菜单 无需js
Aug 15 Javascript
如何手动实现es5中的bind方法详解
Dec 07 Javascript
Angular实现svg和png图片下载实现
May 05 Javascript
jQuery擦除插件eraser使用方法详解
Jan 11 jQuery
京东优选小程序的实现代码示例
Feb 25 Javascript
浅谈JavaScript中的“!!”作用
Aug 03 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
QQ互联一键登录审核不通过的解决方案
2014/09/10 PHP
PHP实现的AES双向加密解密功能示例【128位】
2018/09/03 PHP
js类 from qq
2006/11/13 Javascript
javascript getElementsByClassName函数
2010/04/01 Javascript
js显示时间 js显示最后修改时间
2013/01/02 Javascript
js处理json以及字符串的比较等常用操作
2013/09/08 Javascript
jQuery中toggleClass()方法用法实例
2015/01/05 Javascript
浅谈$(document)和$(window)的区别
2015/07/15 Javascript
基于react组件之间的参数传递(详解)
2017/09/05 Javascript
React数据传递之组件内部通信的方法
2017/12/31 Javascript
Vue组件通信的四种方式汇总
2018/02/08 Javascript
element vue Array数组和Map对象的添加与删除操作
2018/11/14 Javascript
layui 上传插件 带预览 非自动上传功能的实例(非常实用)
2019/09/23 Javascript
Javascript作用域和作用域链原理解析
2020/03/03 Javascript
openlayers4实现点动态扩散
2020/08/17 Javascript
[02:10]探秘浦东源深体育馆 DOTA2 Supermajor不见不散
2018/05/17 DOTA
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
在Python的Django框架中为代码添加注释的方法
2015/07/16 Python
Python中的默认参数实例分析
2018/01/29 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
Python自动抢红包教程详解
2019/06/11 Python
jupyter lab文件导出/下载方式
2020/04/22 Python
查看jupyter notebook每个单元格运行时间实例
2020/04/22 Python
Python logging模块写入中文出现乱码
2020/05/21 Python
Python如何把十进制数转换成ip地址
2020/05/25 Python
如何完美的建立一个python项目
2020/10/09 Python
Python下载的11种姿势(小结)
2020/11/18 Python
详解如何在css中引入自定义字体(font-face)
2018/05/17 HTML / CSS
巧用 CSS3的webkit-box-reflect 倒影实现各类动效
2021/03/05 HTML / CSS
详解如何用HTML5 Canvas API控制图片的缩放变换
2016/03/22 HTML / CSS
伦敦眼门票在线预订:London Eye
2018/05/31 全球购物
初中数学教学反思
2014/01/16 职场文书
革命先烈的英雄事迹材料
2014/02/15 职场文书
优秀党员获奖感言
2014/02/18 职场文书
学生检讨书怎么写?
2014/10/10 职场文书
党组织关系的介绍信模板
2019/06/21 职场文书