春节过后,感觉过年吃的油腻的食品转化的脂肪都长到 脑子去了。 根本转不动啊

上班第一天 实在是写不动代码了, 顺手打开多天为看的 收件箱,查看查看邮件,看看春节期间 风云变幻的前端圈又有哪些大事发生。(在这里先为 GitLab 的那位运维同学 默哀一分钟)

在 sg 的邮件中 看到了一道有意思的题目。

原生JS 实现一个 lazyMan 效果

what ? lazyman 是什么鬼,顺其自然的百度了一下

-------------------------------------------------------------假装有分割线------------------------------------------------------------------

把题目转换成 代码就是如下的 一个意思。

题目:

-------------------------------------------------------------假装有分割线------------------------------------------------------------------

答案:

-------------------------------------------------------------假装有分割线------------------------------------------------------------------

思考: 这个题目主要考察哪些内容呢?(我们一步步往下看)

1、首先,看到这个 链式操作 我们能想到的就是 我们原来在使用 JQ 的时候 经常会去 操作DOM 的时候会用到的 $.addClass('xxx').removeClass('xxx') 这样的操作对吧

那么我们仔细思考一下,为什么 这种写法 是能够执行,且不会报错呢?

因为 $.addClass('xxx') 这是一个已经执行过的方法了,就是相当于 上面这种链式写法是 在一个方法后面又去 执行一个方法, 如果原生直接这么去写,肯定是会报错

说 前面这个方法 不包含后面的这个方法。(报这个错误是正常的,为什么呢? 因为本身确实没有啊,因为 func 其本身就是一个 obj,但是这个 obj 中不包含第二个方法)

-------------------------------------------------------------假装有分割线------------------------------------------------------------------

2、那我们首先想到的就是 构造函数, 然后 给这个构造函数的 原型上去添加链式操作需要的方法。

好,那我们先码上 初级 的代码。

// 构造函数
function _lazyMan(name) {
console.log(name);
}

然后我们简单的封装一下

// 构造函数
function _lazyMan(name) {
console.log(name);
} /* 封装 */
function lazyMan(name) {
return new _lazyMan(name);
} lazyMan('zz'); // zz
-------------------------------------------------------------假装有分割线------------------------------------------------------------------

3、我们再给我们的构造函数的原型 添加方法

// 构造函数原型上的  sleep fn
_lazyMan.prototype.sleep = function() {
console.log('i am sleepping');
} // 构造函数原型上的 eat fn
_lazyMan.prototype.eat = function() {
console.log('i am eatting');
}

然后实例化 构造函数,并给其赋值,看结果


lazyMan('zz').eat() // zz
// i am eatting

lazyMan('zz').eat().sleep() // zz
// i am eatting
// error 报错

思考: 为什么会报错么?

上文已给解答。

-------------------------------------------------------------假装有分割线------------------------------------------------------------------

4、我们需要如何去操作才能完成我们 真正想要的东西呢?

我们 是不是需要一个 数组 来存储我们的 事件,然后 有一个 next 的 方法 专门去 执行我们数组中的方法呢?

按照这个思路,我们来尝试着 组织 下我们的代码。


// 构造函数
function _lazyMan(name) {
this.tasks = [];
var that = this;
var fn = (function(n) {
var name = n;
return function() {
console.log(name);
that.next();
}
})(name)
this.tasks.push(fn);
setTimeout(function() {
that.next();
},0)
} // 事件调度函数
_lazyMan.prototype.next = function() {
var fn = this.tasks.shift();
fn && fn();
} // 构造函数原型上的 sleep fn
_lazyMan.prototype.sleep = function() {
var that = this;
var fn = (function() {
return function() {
console.log('i am sleepping');
that.next();
}
})()
this.tasks.push(fn);
return this; // 实现链式调用
} // 构造函数原型上的 eat fn
_lazyMan.prototype.eat = function() {
var that = this;
var fn = (function() {
return function() {
console.log('i am eatting');
that.next();
}
})()
this.tasks.push(fn);
return this; // 实现链式调用
}

其实上面的 代码还可以更加简化一些。

但是在 实际的应用中肯定包含了更多的 变量需要去利用 闭包 去保存、 但是 ES6 的出现 会让代码 一如既往的简洁。


lazyMan('zz').eat().sleep().eat();
lazyMan('zz').sleep().eat();

通过上面的代码,我们发现,我们把 我们链式操作的方法在 构造函数实例化的 时候, 均存入到了 我们定义的 tasks 数组中去了。

在 链式操作调用方法的时候,先去 执行 原型链上的 链式上的 第一个方法,然后再去 执行 next 方法, 去执行 存放在数组中的下一个方法。

继而,我们得到了我们想要的 链式操作 以及 很 明确的 流程控制。

可能有同学会问 流程控制 体现在 哪里。

回过头来,我们再 仔细的看下题目。

为什么会去 执行 两遍这个程序,因为就是为了体现 程序执行过程是 有序的,而不是随便任意执行。 (完)

Javascript 链式操作以及流程控制的更多相关文章

  1. Javascript、C#、php、asp、python 等语言的链式操作的实现

    一.什么是链式操作 把需要的下一步操作的对象通过上一步操作返回回来.使完成某些功能具有持续性. 二.链式操作优点 代码更精简优雅.链式操作能大大精简代码量,多项操作一行代码一气呵成,搞定: 链式操作应 ...

  2. jQuery链式操作[转]

    用过jQuery的朋友都知道他强大的链式操作,方便,简洁,易于理解,如下 $("has_children").click(function(){ $(this).addClass( ...

  3. JQUERY链式操作实例分析

    本文实例讲述了jQuery链式操作.分享给大家供大家参考,具体如下: 从过去的实例中,我们知道jQuery语句可以链接在一起,这不仅可以缩短代码长度,而且很多时候可以实现特殊的效果. <scri ...

  4. jQuery链式操作

    讨论jQuery的文章很多.然而,关于jQuery的链式操作的文章并无多少.好的代码会带来速度的提升.快速渲染和响应意味着更好的用户体验. 下面就来讲讲jQuery的链式操作. 很多时候我们写代码的时 ...

  5. PHP设计模式:类自动载入、PSR-0规范、链式操作、11种面向对象设计模式实现和使用、OOP的基本原则和自动加载配置

    一.类自动载入 SPL函数 (standard php librarys) 类自动载入,尽管 __autoload() 函数也能自动加载类和接口,但更建议使用 spl_autoload_registe ...

  6. js实现链式操作

    前言:前不久阿里远程面试时问了我一个问题,如下: function Person(){}; var person = new Person(); //实现person.set(10).get()返回2 ...

  7. Javascript 链式作用域 function fn(){}和var fn=function(){}区别

    其实对于Javascript链式作用域的描述,包括,JS权威指南,都有些太冗长了--但是很准确:JavaScript中的函数运行在他们被定义的作用域里,而不是他们被执行的作用域里. 这句话有点难懂,但 ...

  8. 用php实现一个简单的链式操作

    最近在读<php核心技术与最佳实践>这本书,书中第一章提到用__call()方法可以实现一个简单的字符串链式操作,比如,下面这个过滤字符串然后再求长度的操作,一般要这么写: strlen( ...

  9. PHP中的__toString方法(实现JS里的链式操作)

    _toString方法是在打印对象时自动调用的魔术方法,如果不声明会报以下错 Catchable fatal error: Object of class String could not be co ...

随机推荐

  1. HDU 2243考研路茫茫——单词情结 (AC自动机+矩阵快速幂)

    背单词,始终是复习英语的重要环节.在荒废了3年大学生涯后,Lele也终于要开始背单词了. 一天,Lele在某本单词书上看到了一个根据词根来背单词的方法.比如"ab",放在单词前一般 ...

  2. SpringBoot使用Elastic-Job

    本文介绍SpringBoot整合Elastic-Job分布式调度任务(简单任务). 1.有关Elastic-Job Elastic-Job是当当网开源的分布式任务调度解决方案,是业内使用较多的分布式调 ...

  3. JavaScript处理null、undefined和空值

    最近一直在写前端,在使用jquery的ajax请求然后处理返回值的时候,经常会遇到返回值为undefined或者"null"的情况,很是头疼,而返回接口是来自于其他公司的,所以这种 ...

  4. 展开被 SpringBoot 玩的日子 《 六 》 整合 Mybatis

    上次整合了JPA ,但是很多人觉得JPA 并不是那么好用,这都是习惯问题,我本人也比较习惯Mybatis ,所以,今天就整合一下Mybatis,到网上找了一下关于spring boot和mybatis ...

  5. BZOJ.4145.[AMPPZ2014]The Prices(状压DP)

    BZOJ 比较裸的状压DP. 刚开始写麻烦惹... \(f[i][s]\)表示考虑了前\(i\)家商店,所买物品状态为\(s\)的最小花费. 可以写求一遍一定去\(i\)商店的\(f[i]\)(\(f ...

  6. nodejs, 阿里oss上传下载图片

    const archiver = require('archiver')const send = require('koa-send')const oss = require('ali-oss').W ...

  7. Python数据分析实战

    Python数据分析实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1nlHM1IW8MYg3z79TUwIsWg 提取码:ux8t 复制这段内容后打开百度网盘手 ...

  8. PHP调用微博接口实现微博登录的方法示例

    在平时项目开发过程中,除了注册本网站账号进行登录之外,还可以调用第三方接口进行登录网站.这里以微博登录为例.微博登录包括身份认证.用户关系以及内容传播.允许用户使用微博帐号登录访问第三方网站,分享内容 ...

  9. PHP序列号生成函数和字符串替换函数代码

    /** * 序列号生成器 */ function snMaker($pre = '') { $date = date('Ymd'); $rand = rand(1000000,9999999); $t ...

  10. Xmanager6 下载地址

    Xmanager-6标准版下载地址 http://xiazai.xshellcn.com/trial/Xmanager-6.0.0080_yy.exe Xmanager-6企业版下载地址 http:/ ...