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修改css样式style
Apr 15 Javascript
extjs 学习笔记(三) 最基本的grid
Oct 15 Javascript
基于Jquery实现的一个图片滚动切换
Jun 21 Javascript
jquery.post用法关于type设置问题补充
Jan 03 Javascript
jQuery替换textarea中换行的方法
Jun 10 Javascript
javascript中Date format(js日期格式化)方法小结
Dec 17 Javascript
js基于setTimeout与setInterval实现多线程
Jun 17 Javascript
jQuery图片切换动画特效
Nov 02 Javascript
JavaScript数组迭代方法
Mar 03 Javascript
Vue路由之JWT身份认证的实现方法
Aug 26 Javascript
Vue 实现html中根据类型显示内容
Oct 28 Javascript
js中apply和call的理解与使用方法
Nov 27 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面向对象全攻略 (十五) 多态的应用
2009/09/30 PHP
PHP的博客ping服务代码
2012/02/04 PHP
php实现Session存储到Redis
2015/11/11 PHP
给PHP开发者的编程指南 第一部分降低复杂程度
2016/01/18 PHP
Yii2框架使用计划任务的方法
2016/05/25 PHP
PHP实现文件下载【实例分享】
2017/04/28 PHP
PHP里的$_GET数组介绍
2019/03/22 PHP
新页面打开实际尺寸的图片
2006/08/25 Javascript
js资料toString 方法
2007/03/13 Javascript
JS限制上传图片大小不使用控件在本地实现
2012/12/19 Javascript
javascript常用对话框小集
2013/09/13 Javascript
JS和函数式语言的三特性
2014/03/05 Javascript
轻松创建nodejs服务器(1):一个简单nodejs服务器例子
2014/12/18 NodeJs
深入理解JavaScript中的对象复制(Object Clone)
2016/05/18 Javascript
js时间比较 js计算时间差的简单实现方法
2016/08/26 Javascript
JS中setTimeout和setInterval的最大延时值详解
2017/02/13 Javascript
React组件生命周期详解
2017/07/03 Javascript
使用Vue中 v-for循环列表控制按钮隐藏显示功能
2019/04/23 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
[54:53]2014 DOTA2国际邀请赛中国区预选赛 LGD-GAMING VS CIS 第二场
2014/05/23 DOTA
运动检测ViBe算法python实现代码
2018/01/09 Python
Python subprocess模块详细解读
2018/01/29 Python
Python图像处理库PIL的ImageGrab模块介绍详解
2020/02/26 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
澳大利亚UGG工厂直销:Australian Ugg Boots
2017/10/14 全球购物
法国隐形眼镜网站:VisionDirect.fr
2020/03/03 全球购物
护理自荐信范文
2013/10/05 职场文书
学校消防安全制度
2014/01/30 职场文书
高一新生军训感言
2014/03/02 职场文书
口才训练演讲稿范文
2014/09/16 职场文书
高中校园广播稿
2014/10/21 职场文书
任命书怎么写
2015/03/02 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
python自然语言处理之字典树知识总结
2021/04/25 Python
使用GO语言实现Mysql数据库CURD的简单示例
2021/08/07 Golang
MySQL为数据表建立索引的原则详解
2022/03/03 MySQL