文档章节

javaScript设计模式系列(三) 链式调用

Say_-no
 Say_-no
发布于 2017/07/03 23:11
字数 1196
阅读 6
收藏 1

写在最前面:

这种技术包含两个部分:一个是创建代表HTML元素的对象工厂(其实就是获取THML元素的方法,在工厂模式中会讲),另一个就是一些可以操作HTML元素的方法。当然上面说的不清晰也没有关系,文章很短,希望各位朋友看完一定有新发现。

正文:

先来个简单的jquery例子:

$('.box').find('.box2').siblings('.box2').css({'color':'red','border:1px solid green'});

为什么可以通过点( . )来实现链式调用,先思考一下什么可以通过点(.)来操作。没错,是对象。有了对象就可以通过点( . )来调用其中的属性。而jquery正式通过点(.)来调用上一步操作中返回的对象,从而实现链式调用。

既然知道的原理,就来写写试试。既然是每次操作返回的都是当前对象,可以尝试用this来指代当前对象。

现在向我们自己的方法库添加一些方法:

//通过在Function的原型上扩展一个添加方法的方法
//并return this 使得返回当前对象,从而实现链式调用
Function.prototype.addMothed = function(mothedName, mothed) {
  this[mothedName] = mothed;
  return this;
};
(function() {
  function myMothed() {
    console.log('主方法');
  }
  //通过链式调用不断添加方法
  myMothed.addMothed('mothed1', function() {
    console.log('方法1');
  }).addMothed('mothed2', function() {
    console.log('方法2');
  }).addMothed('mothed3', function() {
    console.log('方法3');
  })
  myMothed();//主方法
  myMothed.mothed1();//方法1
  myMothed.mothed2();//方法2
  myMothed.mothed3();//方法3
})()

确实成功的向我们自己的方法库中通过链式调用的方法添加了一些方法,并且成功调用,但是看起来没啥鸟用。那我们就换个角度看:

//通过在Function的原型上扩展一个添加方法的方法
//并return this 使得返回当前对象,从而实现链式调用
Function.prototype.addMothed = function(mothedName, mothed) {
  this.prototype[mothedName] = mothed;
  return this;
};
(function() {
  function MyMothed(num) {
    this.num = num;
  }
  //通过链式调用不断添加方法
  MyMothed.addMothed('mothed1', function() {
    console.log(this.num+1);
    return this;
  }).addMothed('mothed2', function() {
    console.log(this.num+2);
    return this;
  }).addMothed('mothed3', function() {
    console.log(this.num+3);
    return this;
  })
//工厂函数
window.$ = function(num){
 return new MyMothed(num);
}
  //和上面不一样的是每个方法下面都有一个return this
  //使我们可以通过链式调用每个方法返回的元素
  //下面使用我们的方法
  $(10).mothed1().mothed2().mothed3();// 11 12 13
})()

这样的理解是不是更近了一步,通过链式调用添加方法,在通过链式调用使用方法。在看一个实际一点的例子,通过链式调用操作DOM。

<div id="box"></div>
Function.prototype.addMothed = function (mothedName, mothed) {
  this.prototype[mothedName] = mothed;
  return this;
};
(function () {
  function _$(els) {
    this.box = document.getElementById(els);
  }
  //通过链式调用不断添加方法
  _$.addMothed('setWidth', function (val) {
    console.log(this);
    this.box.style.width = val;
    return this;
  }).addMothed('setHeight', function (val) {
    this.box.style.height = val;
    return this;
  }).addMothed('setBackground', function (val) {
    this.box.style.backgroundColor = val;
    return this;
  })
  window.$ = function (els) {
    return new _$(els);
  }
  $('box').setWidth('100px').setHeight('100px').setBackground('red');
})()

没错我们就得到了一个长宽为100px,背景是红色的正方形。

现在我们要考虑一个问题,如果我用$表示现在的这个可以链式调用的方法,但是又引用了jquery库,那么就会被我们的方法覆盖,怎办办? 我们可以像下面的方法来绑定版本,或者说更新版本,只需要改其中的一小段代码。

window.$ = function (els) {
  return new _$(els);
}
//修改为
window.installVersion =function(scope,interface){
    scope[interface] = function(els){
      return new _$(els);
    }
}
//这样使用
installVersion(window,'$');

最后一个关键技巧是通过回调从链式调用中获取数据。

先看一个例子:

//有一个动物园,每天的流程是吃饭,做游戏,睡觉  还有一个查看开不开心的方法
(function () {
  function Zoom(animal) {
    this.animal = animal;
    this.mood = false;
  }
  Zoom.prototype = {
    constructor: Zoom,
    eat: function (fruit) {
      console.log(this.animal + '今天吃了' + fruit);
      return this;
    },
    play: function (toy) {
      console.log(this.animal + '今天玩了' + toy);
      this.mood = true;
      return this;
    },
    sleep: function () {
      console.log(this.animal + '睡觉了');
      return this;
    }
  }
  window.zoom = function (animal) {
    return new Zoom(animal);
  }
  function checkMood(){
    console.log(this.mood);
  }
  var dog =  zoom('dog');

  dog.eat('苹果').play('秋千').sleep();//dog今天吃了苹果 --> dog今天玩了秋千 --> dog睡觉了
  //如果现在要求玩过之后必须要查看开不开心才能睡觉
  dog.eat('苹果').play('秋千');
  checkMood.call(dog);
  dog.sleep();
})()

这种取值的方法就回切断链式调用,所以我们要通过回调的方法来取值,下面是改写的方法:

(function () {
  function Zoom(animal) {
    this.animal = animal;
    this.mood = false;
  }
  Zoom.prototype = {
    constructor: Zoom,
    eat: function (fruit) {
      console.log(this.animal + '今天吃了' + fruit);
      return this;
    },
    play: function (toy,callback) {
      console.log(this.animal + '今天玩了' + toy);
      this.mood = true;
      callback.call(this);
      return this;
    },
    sleep: function () {
      console.log(this.animal + '睡觉了');
      return this;
    }
  }
  window.zoom = function (animal) {
    return new Zoom(animal);
  }
  function checkMood(){
    console.log(this.mood);
  }
  var dog =  zoom('dog');

  dog.eat('苹果').play('秋千',checkMood).sleep();//dog今天吃了苹果 --> dog今天玩了秋千 --> ture --> dog睡觉了
})()

 

© 著作权归作者所有

Say_-no
粉丝 1
博文 6
码字总数 9308
作品 0
昆明
私信 提问
《JavaScript设计模式与开发实践》原则篇(2)—— 最少知识原则

最少知识原则(LKP)说的是一个软件实体应当尽可能少地与其他实体发生相互作用。这 里的软件实体是一个广义的概念,不仅包括对象,还包括系统、类、模块、函数、变量等。 单一职责原则指导我们...

嗨呀豆豆呢
2018/12/30
0
0
《JavaScript设计模式与开发实践》最全知识点汇总大全

系列文章: 《JavaScript设计模式与开发实践》基础篇(1)—— this、call 和 apply 《JavaScript设计模式与开发实践》基础篇(2)—— 闭包和高阶函数 《JavaScript设计模式与开发实践》模式...

嗨呀豆豆呢
01/04
0
0
JavaScript设计模式系列三之单例模式(附案例源码)

文章初衷 设计模式其实旨在解决语言本身存在的缺陷 目前javaScript一些新的语法特性已经集成了一些设计模式的实现, 大家在写代码的时候,没必要为了用设计模式而去用设计模式, 那么我这边为什...

小钱钱阿圣
2017/09/22
0
0
《JavaScript设计模式与开发实践》模式篇(12)—— 装饰者模式

在传统的面向对象语言中,给对象添加功能常常使用继承的方式,但是继承的方式并不灵活, 还会带来许多问题:一方面会导致超类和子类之间存在强耦合性,当超类改变时,子类也会随之 改变;另一方...

嗨呀豆豆呢
2018/12/25
0
0
[译] 你需要知道的7个JavaScript设计模式

原文地址 设计模式在JavaScript中用于在JavaScript的Web项目中解决一些常见问题的可重复解决方案。 简介 JavaScript设计模式是非常适合作为一种模式去提供问题的解决方案,但这并不能代表可以...

金刚小仓
09/30
0
0

没有更多内容

加载失败,请刷新页面

加载更多

编程作业20190210900169

1编写一个程序,提示用户输入名和姓,然后以“名,姓”的格式打印出来。 #include <stdio.h>#include <stdlib.h> int main(){ char firstName[20]; char lastName[20]; print......

1李嘉焘1
21分钟前
4
0
补码的优点及原理分析

只讨论整数 1.计算机内部为什么没有减法器? 减法运算本身其实就是加法,如x - y即x +(-y),所以只需要将负数成功表示出来并可以参加加法运算,那加法器就可同时实现“+”和“-”的运算。这...

清自以敬
36分钟前
63
0
Docker 可视化管理 portainer

官网安装指南: https://portainer.readthedocs.io/en/latest/deployment.html docker-compose.yml 位置,下载地址:https://downloads.portainer.io/docker-compose.yml...

Moks角木
今天
5
0
Spring Security 实战干货:必须掌握的一些内置 Filter

1. 前言 上一文我们使用 Spring Security 实现了各种登录聚合的场面。其中我们是通过在 UsernamePasswordAuthenticationFilter 之前一个自定义的过滤器实现的。我怎么知道自定义过滤器要加在...

码农小胖哥
今天
8
0
常见分布式事务解决方案

1 微服务的发展 微服务倡导将复杂的单体应用拆分为若干个功能简单、松耦合的服务,这样可以降低开发难度、增强扩展性、便于敏捷开发。当前被越来越多的开发者推崇,很多互联网行业巨头、开源...

asdf08442a
今天
5
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部