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

  1. // 不使用链式调用
  2. const element = $(ele);
  3. element.addClass('red');
  4. element.removeClass('green');
  5. element.show();
  6. // 链式调用
  7. $(ele)
  8. .addClass('red')
  9. .removeClass('green')
  10. .show();

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

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

  1. // 通过立即执行函数,声明了一个_$函数,并且将一个$函数挂载到window上,并且每次调用$()的时候,返回的其实是个_$实例,由于原型对象方法里,执行最后都会返回一个this,因此就可以执行链式调用。
  2. (function () {
  3. // 构造函数
  4. function _$(selector) {
  5. // ...
  6. }
  7. _$.prototype = {
  8. addClass: function (className) {
  9. // ...
  10. return this;
  11. },
  12. removeClass: function (className) {
  13. // ...
  14. return this;
  15. },
  16. show: function () {
  17. // ...
  18. return this;
  19. }
  20. };
  21. _$.prototype.constructor = _$;
  22. // 每次调用$()的时候,返回的其实是个_$实例
  23. window.$ = function () {
  24. return new _$(arguments);
  25. }
  26. })();
  27. // 通过这种方式,我们就可以直接使用$的链式调用
  28. $(ele)
  29. .addClass('red')
  30. .removeClass('green')
  31. .show();

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

  1. (function () {
  2. // 构造函数
  3. function _$(selector) {
  4. // ...
  5. }
  6. _$.prototype = {
  7. addClass: function (className) {
  8. // ...
  9. return this;
  10. },
  11. removeClass: function (className) {
  12. // ...
  13. return this;
  14. },
  15. show: function () {
  16. // ...
  17. return this;
  18. }
  19. };
  20. _$.prototype.constructor = _$;
  21. // 增加一个安装器
  22. window.installHelper = function (scope, interface) {
  23. scope[interface] = function () {
  24. return new _$(arguments);
  25. }
  26. }
  27. })();
  28. // 而用户就可以这样使用它来自定义挂载对象以及其命名
  29. installHelper(window, '$');
  30. $(ele).show();

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

  1. // 第一种方法,当遇到取值器,则直接返回数据
  2. (function () {
  3. // 构造函数
  4. function _$(selector) {
  5. this.ele = document.querySelector(selector);
  6. // ...
  7. }
  8. _$.prototype = {
  9. addClass: function (className) {
  10. // ...
  11. return this;
  12. },
  13. // 取值器
  14. getClass: function () {
  15. // ...
  16. return this.ele.className;
  17. }
  18. };
  19. _$.prototype.constructor = _$;
  20. })();
  21. // 第二种方式,通过回调的方式来处理数据
  22. (function () {
  23. // 构造函数
  24. function _$(selector) {
  25. this.ele = document.querySelector(selector);
  26. // ...
  27. }
  28. _$.prototype = {
  29. addClass: function (className) {
  30. // ...
  31. return this;
  32. },
  33. getClass: function (cb) {
  34. // ...
  35. cb.call(this, this.ele.className);
  36. return this;
  37. }
  38. };
  39. _$.prototype.constructor = _$;
  40. })();

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

Javasript设计模式之链式调用的更多相关文章

  1. 仿jQuery之链式调用

    链式调用的形式其实就是对象调用一连串的方法.为什么能连续调用这么多的方法?因为调用方法返回调用的对象,于是乎就可以一如既往,一往无前地调用下去.链式调用的原理就是在方法中返回执行上下文this,每次调 ...

  2. spring aop 之链式调用

    关关雎鸠,在河之洲.窈窕淑女,君子好逑. 概述 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横 ...

  3. Jquery复习(三)之链式调用

    通过 jQuery,可以把动作/方法链接在一起. Chaining 允许我们在一条语句中运行多个 jQuery 方法(在相同的元素上). jQuery 方法链接 直到现在,我们都是一次写一条 jQue ...

  4. jquery之链式调用,层级菜单

    一. 链式调用的含义 jquery对象的方法会在执行完后返回这个jquery对象,所有jquery对象的方法可以连起来写: $('#div1') // id为div1的元素 .children('ul ...

  5. 如何写 JS 的链式调用 ---》JS 设计模式《----方法的链式调用

    1.以$ 函数为例.通常返回一个HTML元素或一个元素集合. 代码如下: function $(){ var elements = []; ;i<arguments.length;i++){ v ...

  6. JavaScript设计模式——方法的链式调用

    方法的链式调用: (function() { //私有类 function _$ (els) { this.elements = []; for(var i = 0, len = els.length ...

  7. js原生设计模式——2面向对象编程之js原生的链式调用

    技巧点:对象方法中返回当前对象就可以链式调用了,即方法中写return this; <!DOCTYPE html><html lang="en"><h ...

  8. JavaScript设计模式-8.链式调用

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  9. 《javascript设计模式》笔记之第六章:方法的链式调用

    这一章要实现的就是jQuery的那种链式调用,例子: $(this).setStyle('color', 'green').show(); 一:调用链的结构: 首先我们来看一下最简单的$()函数的实现 ...

随机推荐

  1. IDEA2017注册码

    1. 到网站 http://idea.lanyus.com/ 获取注册码. 2.填入下面的license server: http://intellij.mandroid.cn/ http://ide ...

  2. 20165226 2017-2018-3 《Java程序设计》第5学习总结

    20165226 2017-2018-3 <Java程序设计>第5周学习总结 教材学习内容总结 第七章 内部类与异常类 匿名类创建对象: new Bank() { 匿名类的类体 }: 异常 ...

  3. Jquery判断单选框是否选中和获取选中的值

    第一种:利用选中值判断选中 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http ...

  4. vim的配置

    修改根目录下.vimrc文件: 1.设定解码,支持中文 set fileencodings=utf-8,ucs-born,gb18030,gbk,gb2312,cp936 set termencodi ...

  5. 201621123040《Java程序设计》第七周学习总结

    1.本周学习总结 1.1思维导图:Java图形界面总结 2.书面作业 2.1GUI中的事件处理 2.1.1写出事件处理模型中最重要的几个关键词. 关键词:事件 事件源 事件监听器 2.1.2任意编写事 ...

  6. UserControl 用户定义组件

    <pages> <namespaces> <add namespace="System.Web.Optimization" /> </na ...

  7. 利用python实现简单随机验证码

    #!/usr/bin/env python # -*- coding:utf-8 -*- import random temp ='' for i in range(6): num = random. ...

  8. LR录制脚本的时候打不开浏览器问题

    使用Chrome时,显示开始录制但是Action中无任何脚本,即脚本没成功生成. 使用Firefox(最新版),一直关闭程序,详细信息有StackHash_0a9e. 使用IE11时,也是显示开始录制 ...

  9. linux下面根据不同的日期创建不同文件,一般用户数据库的备份的shell编程

    [root@www scripts]# vi sh03.sh #!/bin/bash # Program: #  Program creates three files, which named by ...

  10. 新概念英语(1-137)A pleasant dream

    Lesson 137 A pleasant dream 美好的梦 Listen to the tape then answer this question. What would Julie like ...