Javasript设计模式之链式调用
写过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值,就可以让该类变化一个支持方法链式调用的类。而如果要让取值器方法也支持链式调用,就可以在取值器里使用回调的方式来解决这个问题。
Javasript设计模式之链式调用的更多相关文章
- 仿jQuery之链式调用
链式调用的形式其实就是对象调用一连串的方法.为什么能连续调用这么多的方法?因为调用方法返回调用的对象,于是乎就可以一如既往,一往无前地调用下去.链式调用的原理就是在方法中返回执行上下文this,每次调 ...
- spring aop 之链式调用
关关雎鸠,在河之洲.窈窕淑女,君子好逑. 概述 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横 ...
- Jquery复习(三)之链式调用
通过 jQuery,可以把动作/方法链接在一起. Chaining 允许我们在一条语句中运行多个 jQuery 方法(在相同的元素上). jQuery 方法链接 直到现在,我们都是一次写一条 jQue ...
- jquery之链式调用,层级菜单
一. 链式调用的含义 jquery对象的方法会在执行完后返回这个jquery对象,所有jquery对象的方法可以连起来写: $('#div1') // id为div1的元素 .children('ul ...
- 如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用
1.以$ 函数为例.通常返回一个HTML元素或一个元素集合. 代码如下: function $(){ var elements = []; ;i<arguments.length;i++){ v ...
- JavaScript设计模式——方法的链式调用
方法的链式调用: (function() { //私有类 function _$ (els) { this.elements = []; for(var i = 0, len = els.length ...
- js原生设计模式——2面向对象编程之js原生的链式调用
技巧点:对象方法中返回当前对象就可以链式调用了,即方法中写return this; <!DOCTYPE html><html lang="en"><h ...
- JavaScript设计模式-8.链式调用
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 《javascript设计模式》笔记之第六章:方法的链式调用
这一章要实现的就是jQuery的那种链式调用,例子: $(this).setStyle('color', 'green').show(); 一:调用链的结构: 首先我们来看一下最简单的$()函数的实现 ...
随机推荐
- Bean validation
公司测试非常严格,要求我们对每个参数的长度进行校验,提了一个参数长度校验的单,然后我们老大就把我们的代码全部打回去了.... 一个bean类中往往有超多变量,如果一个个写if else,够呛,而且圈复 ...
- 248&258--高级软件工程第三次作业
0 小组成员 马帅 / 2017202110248 齐爽爽 / 2017282110258 1 项目 GitHub 地址 GitHub:https://github.com/whumashuai/QT ...
- 201621123062《java程序设计》第11周作业总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 思维导图: 2. 书面作业 本次PTA作业题集多线程 2.1. 源代码阅读:多线程程序BounceThread 2 ...
- 学号:201621123032 《Java程序设计》第12周学习总结
1:本周学习总结 1.1:以你喜欢的方式(思维导图或其他)归纳总结多流与文件相关内容. 2:面向系统综合设计-图书馆管理系统或购物车 2.1: 简述如何使用流与文件改造你的系统.文件中数据的格式如何? ...
- Linux下I/O多路转接之select --fd_set
fd_set 你终于还是来了,能看到这个标题进来的,我想,你一定是和我遇到了一样的问题,一样的疑惑,接下来几个小时,我一定竭尽全力,写出我想说的,希望也正是你所需要的: 关于Linux下I/O多路转接 ...
- python array 使用创建10万浮点数
from array import array from random floats = array('d',random((for i in range(10**7)) fp = open('flo ...
- iOS开发所有KeyboardType与图片对应展示
1.UIKeyboardTypeAlphabet 2.UIKeyboardTypeASCIICapable 3.UIKeyboardTypeDecimalPad 4.UIKeyboardTypeDe ...
- PostMan 调用WCF Rest服务
问题描述: 现在有已有的WCF服务,但是ajax是不能请求到这个服务的: 需要把WCF转成WCF REST 的风格. 以下是从WCF转 WCF REST的步骤 1.首先在接口定义的地方加上 请求 We ...
- MSSQL 2000 错误823恢复
一.故障描述 MSSQL Server 2000 附加数据库错误823,附加数据库失败.数据库没有备份,不能通过备份恢复数据库,急需恢复数据库中的数据. 二.故障分析SQL Server数据库 823 ...
- js定时刷新页面.
//页面定时刷新.2017.09.27 $(document).ready(function () { self.setInterval(function () { var d = new Date( ...