构造函数实例化强制new

  1. function A(n) {
  2. this.name=n
  3. if (new.target == A) {
  4. console.log(1)
  5. return new A(n)
  6. }
  7. else {
  8. console.log(2)
  9. return new A(n)
  10. }
  11. }
  12. var a= A(54)
  13. console.log(a)

函数柯里化

  1. function curry(f){
  2. return function curried(...args){
  3. if(args.length==f.length){
  4. return f.apply(null,args)
  5. }
  6. else{
  7. return function(...args2){
  8. return curried.apply(this, args.concat(args2));
  9. }
  10. }
  11. }
  12. }
  13. var a=curry(pan)
  14. console.log(a(1)(2)(3)(4))
  15. function pan(a,b,c,d){
  16. return a+b+c+d
  17. }
  18. console.log(pan.length)

深拷贝

对象

  1. // 方法1版本一
  2. function Copy(obj){
  3. if(typeof obj=='object'){
  4. var sub
  5. if(obj instanceof Array){
  6. sub=[]
  7. }
  8. else{
  9. sub={}
  10. }
  11. for (val in obj){
  12. sub[val]=Copy(obj[val])
  13. }
  14. return sub
  15. }
  16. else{
  17. return obj
  18. }
  19. }
  20. // 方法1版本二
  21. function Copy(obj){
  22. var sub
  23. if(obj.constructor==Object){
  24. sub={}
  25. for (val in obj){
  26. sub[val]=Copy(obj[val])
  27. }
  28. return sub
  29. }
  30. else if(obj.constructor==Array){
  31. sub=[]
  32. for (val in obj){
  33. sub[val]=Copy(obj[val])
  34. }
  35. return sub
  36. }
  37. else{
  38. return obj
  39. }
  40. }
  41. // 方法2
  42. function Copy(obj){
  43. return JSON.parse(JSON.stringify(obj))
  44. }
  45. var a=[1,2,[3,4],5]
  46. var b={a:[1,2],b:{c:3},d:4}
  47. function pan(){}
  48. var c=[1,pan]
  49. var a1=Copy(a)
  50. var b1=Copy(b)
  51. var c1=Copy(c)
  52. //
  53. console.log(a1,b1,c1)

数组

并非实现内部对象深拷贝,是只针对数据内基本类型的拷贝

  1. // 并非对象深拷贝,是只针对数据内基本类型的拷贝
  2. // 方法一:for循环
  3. //方法二
  4. function arrCopy(arr){
  5. var [...temp]=arr
  6. return [...temp]
  7. }
  8. function arrCopy(arr){
  9. return Array.from(arr)
  10. }
  11. function arrCopy(arr){
  12. return arr.slice()
  13. }
  14. function arrCopy(arr){
  15. return [].concat(arr)
  16. }
  17. function arrCopy(arr){
  18. return Object.assign(arr)
  19. }
  20. var a=[1,2,3,[4],5]
  21. var b={a:[1,2],b:{c:3},d:4}
  22. var a1=arrCopy(a)
  23. console.log(a1)
  24. console.log(a1[3]==a[3])

async实现

  1. function myAsync(generator) {
  2. return new Promise((res, rej) => {
  3. // 初始化阶段
  4. var iterator = generator()
  5. var generated = iterator.next()
  6. function step() {
  7. if (generated.done) {
  8. Promise.resolve(generated.value).then(res)
  9. console.log('done')
  10. } else {
  11. Promise.resolve(generated.value).then(val => {
  12. console.log(val)
  13. generated = iterator.next(val)
  14. step()
  15. })
  16. }
  17. }
  18. step()
  19. })
  20. }
  21. // 完整版
  22. // function myAsync(generator) {
  23. // return new Promise((res, rej) => {
  24. // // 初始化阶段
  25. // var iterator = generator()
  26. // var generated
  27. // try {
  28. // generated = iterator.next()
  29. // } catch (err) {
  30. // rej(err)
  31. // }
  32. // function step() {
  33. // if (generated.done) {
  34. // Promise.resolve(generated.value).then(res)
  35. // console.log('done')
  36. // } else {
  37. // Promise.resolve(generated.value).then(val => {
  38. // console.log(val)
  39. // try {
  40. // generated = iterator.next(val)
  41. // } catch (err) {
  42. // rej(err)
  43. // }
  44. // step()
  45. // }, reason => {
  46. // try {
  47. // generated = iterator.throw(reason)
  48. // } catch (err) {
  49. // rej(err)
  50. // }
  51. // })
  52. // }
  53. // }
  54. // step()
  55. // })
  56. // }
  57. // 实验
  58. function* pan() {
  59. var a = yield console.log(5)
  60. var b = yield new Promise((res) => {
  61. setTimeout(() => {
  62. console.log(6);
  63. res(6)
  64. }, 1000)
  65. })
  66. var c = yield console.log(7);
  67. }
  68. myAsync(pan)
  69. console.log(111)

bind实现

  1. Function.prototype.myBind = function (thisArg, ...fixedArgs) {
  2. var self = this
  3. return function newFnc(...args) {
  4. // 考虑将bind之后的函数作为构造函数使用
  5. // if(new.target==newFnc){
  6. // return new self(...fixedArgs,...args)
  7. // }
  8. // else{
  9. return self.call(thisArg, ...fixedArgs, ...args)
  10. // }
  11. }
  12. }

event类观察者模式

  1. class Event {
  2. constructor () {
  3. this.handlers = {}
  4. }
  5. addEventListener (type, handler) {
  6. // 首先判断handlers内有没有type事件容器,没有则创建一个新数组容器
  7. if (!(type in this.handlers)) {
  8. this.handlers[type] = []
  9. }
  10. // 将事件存入
  11. this.handlers[type].push(handler)
  12. }
  13. // 触发事件两个参数(事件名,参数)
  14. dispatchEvent (type, ...params) {
  15. // 若没有注册该事件则抛出错误
  16. if (!(type in this.handlers)) {
  17. return new Error('未注册该事件')
  18. }
  19. // 便利触发
  20. this.handlers[type].forEach(handler => {
  21. handler(...params)
  22. })
  23. }
  24. // 事件移除参数(事件名,删除的事件,若无第二个参数则删除该事件的订阅和发布)
  25. removeEventListener (type, handler) {
  26. // 无效事件抛出
  27. if (!(type in this.handlers)) {
  28. return new Error('无效事件')
  29. }
  30. if (!handler) {
  31. // 直接移除事件
  32. delete this.handlers[type]
  33. } else {
  34. const idx = this.handlers[type].findIndex(ele => ele === handler)
  35. // 抛出异常事件
  36. if (idx === undefined) {
  37. return new Error('无该绑定事件')
  38. }
  39. // 移除事件
  40. this.handlers[type].splice(idx, 1)
  41. if (this.handlers[type].length === 0) {
  42. delete this.handlers[type]
  43. }
  44. }
  45. }
  46. }
  47. var event = new Event() // 创建event实例
  48. // 定义一个自定义事件:"load"
  49. function load (params) {
  50. console.log('load', params)
  51. }
  52. event.addEventListener('load', load)
  53. // 再定义一个load事件
  54. function load2 (params) {
  55. console.log('load2', params)
  56. }
  57. event.addEventListener('load', load2)
  58. // 触发该事件
  59. event.dispatchEvent('load', 'load事件触发')
  60. // 移除load2事件
  61. event.removeEventListener('load', load2)
  62. // 移除所有load事件
  63. event.removeEventListener('load')

new

手写实现 - 图2



手写实现 - 图3

  1. function myNew(f,...args){
  2. // var mythis = Object.create(f.prototype)
  3. //等同于下几句
  4. var mythis={}
  5. mythis.__proto__=f.prototype
  6. var res=f.apply(mythis,args)
  7. if (res && typeof res=='object'){
  8. console.log(res==mythis)
  9. return res
  10. }
  11. else{
  12. console.log(res==mythis)
  13. return mythis
  14. }
  15. }
  16. function Person(name){
  17. this.name=name
  18. return this
  19. }
  20. console.log(myNew(Person,'hello'))

InstanceOf

  1. function myInstanceOf(a,b){
  2. if(a.__proto__==null){
  3. return false
  4. }
  5. // if(a.constructor=b){
  6. if(a.__proto__==b.prototype){
  7. return true
  8. }else{
  9. return myInstanceOf(a.__proto__,b)
  10. }
  11. }
  12. console.log(myInstanceOf([],Function))

Object.create

  1. function create(obj){
  2. function F(){}
  3. F.prototype=obj
  4. return new F()
  5. }
  6. function create(obj){
  7. var a={}
  8. a.__proto__=obj
  9. return a
  10. }
  11. console.log(create({a:123}))

promisify & callbackify

  1. function promisify(callbackFun){
  2. return function p(...args){
  3. return new Promise((res,rej)=>{
  4. callbackFun(...args,(err,data)=>{
  5. if(err){
  6. rej(err)
  7. }
  8. else{
  9. res(data)
  10. }
  11. })
  12. })
  13. }
  14. }
  15. var p=promisify(cb)
  16. p(...args).then()
  17. function callbackify(promise){
  18. return function (...args){
  19. var callback=args.pop()
  20. promise(...args).then(data=>{
  21. callback(null,data)
  22. }).catch(err=>{
  23. callback(err)
  24. })
  25. }
  26. }
  27. var cb=callbackify(p)
  28. cb(...args,(err,data)=>{})

useEffect & useState

  1. // useState
  2. const React = (
  3. function () {
  4. let stateValue
  5. return Object.assign(React, {
  6. useState(initialStateValue) {
  7. stateValue = stateValue || initialStateValue
  8. function setState(value) {
  9. stateValue = value
  10. }
  11. return [stateValue, setState]
  12. }
  13. })
  14. }
  15. )()
  16. //useEffect
  17. const React = (function () {
  18. let deps
  19. return Object.assign(React, {
  20. useEffect(callback, depsArray) {
  21. const shouldUpdate = !depsArray
  22. const depsChange = deps ? !deps.every((depItem, index) => depItem === depsArray[index]) : true
  23. if (shouldUpdate || depsChange) {
  24. callback()
  25. deps = depsArray || []
  26. }
  27. }
  28. })
  29. })()

event类观察者模式

  1. class Event {
  2. constructor () {
  3. this.handlers = {}
  4. }
  5. addEventListener (type, handler) {
  6. // 首先判断handlers内有没有type事件容器,没有则创建一个新数组容器
  7. if (!(type in this.handlers)) {
  8. this.handlers[type] = []
  9. }
  10. // 将事件存入
  11. this.handlers[type].push(handler)
  12. }
  13. // 触发事件两个参数(事件名,参数)
  14. dispatchEvent (type, ...params) {
  15. // 若没有注册该事件则抛出错误
  16. if (!(type in this.handlers)) {
  17. return new Error('未注册该事件')
  18. }
  19. // 便利触发
  20. this.handlers[type].forEach(handler => {
  21. handler(...params)
  22. })
  23. }
  24. // 事件移除参数(事件名,删除的事件,若无第二个参数则删除该事件的订阅和发布)
  25. removeEventListener (type, handler) {
  26. // 无效事件抛出
  27. if (!(type in this.handlers)) {
  28. return new Error('无效事件')
  29. }
  30. if (!handler) {
  31. // 直接移除事件
  32. delete this.handlers[type]
  33. } else {
  34. const idx = this.handlers[type].findIndex(ele => ele === handler)
  35. // 抛出异常事件
  36. if (idx === undefined) {
  37. return new Error('无该绑定事件')
  38. }
  39. // 移除事件
  40. this.handlers[type].splice(idx, 1)
  41. if (this.handlers[type].length === 0) {
  42. delete this.handlers[type]
  43. }
  44. }
  45. }
  46. }
  47. var event = new Event() // 创建event实例
  48. // 定义一个自定义事件:"load"
  49. function load (params) {
  50. console.log('load', params)
  51. }
  52. event.addEventListener('load', load)
  53. // 再定义一个load事件
  54. function load2 (params) {
  55. console.log('load2', params)
  56. }
  57. event.addEventListener('load', load2)
  58. // 触发该事件
  59. event.dispatchEvent('load', 'load事件触发')
  60. // 移除load2事件
  61. event.removeEventListener('load', load2)
  62. // 移除所有load事件
  63. event.removeEventListener('load')

发布-订阅模式

它的优点是为时间是解耦,为对象之间解构,它的应用非常广泛,既可以在异步编程中也可以帮助我们完成更松的解耦。发布-订阅模式还可以帮助我们实现设计模式,从架构上来看,无论MVC还是MVVC都少不了发布-订阅模式的参与。
发布-订阅模式也存在一些缺点,创建订阅本身会消耗一定的时间与内存,也许当你订阅一个消息之后,之后可能就不会发生。发布-订阅模式虽然它弱化了对象与对象之间的关系,但是如果过度使用,对象与对象的必要联系就会被深埋,会导致程序难以跟踪与维护。
案例

  1. //发布-订阅
  2. //有个消息池,存放所有消息
  3. let pubsub = {};
  4. (function(myObj) {
  5. topics = {}
  6. subId = -1;
  7. //订阅者接受参数:(消息名称,回调函数)
  8. myObj.subscribe = function(topic, func) {
  9. //如果订阅的该事件还未定义,初始化
  10. if (!topics[topic]) {
  11. topics[topic] = []
  12. }
  13. //使用不同的token来作为订阅者的索引
  14. let token = (++subId).toString()
  15. topics[topic].push({
  16. token: token,
  17. func: func
  18. })
  19. return token
  20. }
  21. //发布者接受参数(消息名称,参数)
  22. myObj.publish = function(topic, msg) {
  23. //如果发布的该消息没有订阅者,直接返回
  24. if (!topics[topic]) {
  25. return
  26. }
  27. //对该消息的所有订阅者,遍历去执行各自的回调函数
  28. let subs = topics[topic]
  29. subs.forEach(function(sub) {
  30. sub.func(topic, msg)
  31. })
  32. }
  33. myObj.unsubscribe = function(token) {
  34. //对消息列表遍历查找该token是哪个消息中的哪个订阅者
  35. for (let t in topics) {
  36. //对象原型上的属性不予以使用
  37. if(!topics.hasOwnProperty(t)) return
  38. topics[t].forEach(function(sub,index) {
  39. if (sub.token === token) {
  40. //找到了,从订阅者的数组中去掉该订阅者
  41. topics[t].splice(index, 1)
  42. }
  43. })
  44. }
  45. }
  46. })(pubsub)
  47. let sub1 = pubsub.subscribe('Msg::Name', function(topic, msg) {
  48. console.log("event is :" + topic + "; data is :" + msg)
  49. });
  50. let sub2 = pubsub.subscribe('Msg::Name', function(topic, msg) {
  51. console.log("this is another subscriber, data is :" + msg)
  52. });
  53. pubsub.publish('Msg::Name', '123')
  54. pubsub.unsubscribe(sub2)
  55. pubsub.publish('Msg::Name', '456')

其中存储消息的结构用json可以表示为:

topics = {
    topic1: [{ token: 1, func: callback1 }, { token: 2, func: callback2 }],
    topic2: [{ token: 3, func: callback3 }, { token: 4, func: callback4 }],
    topic3: []
}

与事件监听模式

消息池的结构是发布订阅模式与事件监听模式的最大区别。当然,每个消息也可以看做是一个个的事件,topics对象就相当于一个事件处理中心,每个事件都有各自的订阅者。所以事件监听其实就是发布订阅模式的一个简化版本而发布订阅模式的优点就是我们可以查看消息中心的信息,了解有多少信号,每个信号有多少订阅者。

观察者模式

很多情况下,我们都将观察者模式和发布-订阅模式混为一谈,因为都可用来进行异步通信,实现代码的解耦,而不再细究其不同,但是内部实现还是有很多不同的。

  • 整体模型的不同:发布订阅模式是靠信息池作为发布者和订阅者的中转站的,订阅者订阅的是信息池中的某个信息;而观察者模式是直接将订阅者订阅到发布者内部的,目标对象需要负责维护观察者,也就是观察者模式中订阅者是依赖发布者的。
  • 触发回调的方式不同:发布-订阅模式中,订阅者通过监听特定消息来触发回调;而观察者模式是发布者暴露一个接口(方法),当目标对象发生变化时调用此接口,以保持自身状态的及时改变。

观察者模式很好的应用是MVC架构,当数据模型更新时,视图也发生变化。从数据模型中将视图解耦出来,从而减少了依赖。但是当观察者数量上升时,性能会有显著下降。

//观察者模式
var Subject=function(){
    this.observers=[];
}
Subject.prototype={
    subscribe:function(observer){
        this.observers.push(observer);
    },
    unsubscribe:function(observer){
        var index=this.observers.indexOf(observer);
        if (index>-1) {
            this.observers.splice(index,1);
        }
    },
    notify:function(observer,msg){
        var index=this.observers.indexOf(observer);
        if (index>-1) {
            this.observers[index].notify(msg)
        }
    },
    notifyAll:function(msg){
        this.observers.forEach(function(observe,msg){
            observe.notify(msg)
        })
    }
}
var Observer=function(){
    return {
        notify:function(msg){
            console.log("received: "+msg);
        }
    }
}
var subject=new Subject();
var observer0=new Observer();
var observer1=new Observer();
var observer2=new Observer();
var observer3=new Observer();
subject.subscribe(observer0);
subject.subscribe(observer1);
subject.subscribe(observer2);
subject.subscribe(observer3);
subject.notifyAll('all notified');
subject.notify(observer2,'asda');

Promise实现



class Promise {
    constructor(executor) {
      //每个promise实例均有
      //   state、
      //   value、
      //   reason、
      //   res队列、
      //   rej队列
      //这几个实例属性
        this.state = 'pending';
        this.value = undefined;
        this.reason = undefined;
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];
        let resolve = value => {
            if (this.state === 'pending') {
                this.state = 'fulfilled';
                this.value = value;
              //针对的是
              //promise1.then(a)
              //promise1.then(b)
              //等同一个promise的多个then非链式调用
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        };
        let reject = reason => {
            if (this.state === 'pending') {
                this.state = 'rejected';
                this.reason = reason;
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        };
        try {
            executor(resolve, reject);
        } catch (err) {
            reject(err);
        }
    }
    then(onFulfilled, onRejected) {
        onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
        let promise2 = new Promise((resolve, reject) => {
            if (this.state === 'fulfilled') {
                setTimeout(() => {
                    try {
                      //x为then函数内部返回值,promise2为新创建的promise,
                      //resolvePromise可处理x为promise的情况,并可以递归等待状态resolve
                      //当x不是promise,将promise2的最终value设为x
                        let x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            };
            if (this.state === 'rejected') {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e);
                    }
                }, 0);
            };
            if (this.state === 'pending') {
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    }, 0);
                });
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject);
                        } catch (e) {
                            reject(e);
                        }
                    }, 0)
                });
            };
        });
        return promise2;
    }
    catch(fn) {
        return this.then(null, fn);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    if (x === promise2) {
        return reject(new TypeError('Chaining cycle detected for promise'));
    }
    let called;
    //函数视同对象
    if (x != null && (typeof x === 'object' || typeof x === 'function')) {
        try {
            let then = x.then;
            if (typeof then === 'function') {
                then.call(x, y => {
                    if (called) return;
                    called = true;
                    resolvePromise(promise2, y, resolve, reject);
                }, err => {
                    if (called) return;
                    called = true;
                    reject(err);
                })
            } else {
                resolve(x);
            }
        } catch (e) {
            if (called) return;
            called = true;
            reject(e);
        }
    } else {
        resolve(x);
    }
}

// resolve方法
Promise.resolve = function (val) {
    return new Promise((resolve, reject) => {
        resolve(val)
    });
}
//reject方法
Promise.reject = function (val) {
    return new Promise((resolve, reject) => {
        reject(val)
    });
}
//race方法 
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(resolve, reject)
        };
    })
}
//all方法(获取所有的promise,都执行then,把结果放到数组,一起返回)
Promise.all = function (promises) {
    let arr = [];
    let i = 0;
    function processData(index, data) {
        arr[index] = data;
        i++;
        if (i == promises.length) {
            resolve(arr);
        };
    };
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(data => {
                processData(i, data);
            }, reject);
        };
    });
}


// console.log(
new Promise((res, rej) => {
    res(1)
})
    .then(data => {
        console.log(2)
        console.log('data', data)
        // return 999
    }).then(res => {
        console.log('res', res);
    })
// )

Lazy

function lazy(f) {
  return class Lazy extends React.Component {
    constructor(props) {
      super(props)

      this.state = {
        loading: true
      }

      f().then(Comp => {
        this.Comp = Comp
        this.setState({
          loading: false
        })
      })
    }

    render() {
      if (this.state.loading) {
        return null
      } else {
        var Comp = this.Comp
        var {children, ...props} = this.props
        return <Comp {...props}>{children}</Comp>
      }
    }
  }
}



var Comp = React.lazy2({
  compoent: () => import('./MyComponent'),
  loading: (props) => {
    return <div>loading...</div>
  },
  error: (props) => {
    return <div>error</div>
  },
  timeout: 3000,
  delay: 200,
})

function lazy(f) {
  class Lazy extends React.Component {
    constructor(props) {
      super(props)

      this.state = {
        loading: true
      }

      f().then(Comp => {
        this.Comp = Comp
        this.setState({
          loading: false
        })
      })
    }

    render() {
      if (this.state.loading) {
        return <span style={{color:'red'}}>loading...</span>
      } else {
        var Comp = this.Comp
        var {children, forwardRef, ...props} = this.props
        return <Comp ref={forwardRef} {...props}>{children}</Comp>
      }
    }
  }

  return React.forwardRef((props, ref) => {
    return <Lazy {...props} forwardRef={ref}/>
  })
}



React.lazy2 = function(obj) {
  return function LazyComp(props) {
    var [delay, setDelay] = useState(false)
    setTimeout(() => {
      setDelay(true)
    }, obj.delay)

    var [error, setError] = useState(false)
    var [timeout, setTO] = useState(false)
    setTimeout(() => {
      setDelay(true)
    }, obj.timeout)

    var [loading, setLoading] = useState(false)
    var [ActuralComp, setActuralComp] = useState(null)

    obj.compoent().then(comp => {
      setLoading(false)
      setActuralComp(comp)
    }).catch(() => {
      setError(true)
    })

    if (error) {
      var Loading = obj.loading
      return <Loading {...props}/>
    }

    if (delay) {
      var Delay = obj.delay
      return <Delay {...props}/>
    }

    if (loading) {
      return null
    } else {
      return <ActuralComp {...props}/>
    }
  }
}

Lazyman

function LazyMan(name) {
  return new _LazyMan(name)
}
class _LazyMan {
  constructor(name) {
    this.name = () => {
      console.log(name)

    }
    this.tasks = [this.name]
    this.time = null
    this.run.call(this)
    //ES6的class只能通过new来使用,不能直接运行。
    // if(new.target!=LayMan){
    //   return this
    // }
  }
  run() {
    if (this.time) {
      clearTimeout(this.time)
      this.time = null
    }
    this.time = setTimeout(async () => {
      for (var task of this.tasks) {
        await task()
      }
    })
  }

  eat(event) {
    var task = () => {
      console.log(event)
    }
    this.tasks.push(task)
    return this
  }
  sleep(num) {
    var task = () => {
      return new Promise((res,rej)=>{
        setTimeout(()=>{
          res()
          console.log('Wake up after '+num)
        },num*1000)
      })
    }
    this.tasks.push(task)
    return this
  }
  sleepFirst(num) {
    var task = () => {
      return new Promise((res,rej)=>{
        setTimeout(()=>{
          res()
          console.log('Wake up after '+num)
        },num*1000)
      })
    }
    this.tasks.unshift(task)
    return this
  }



}
// LazyMan('Hank').eat('dinner').eat('supper')
// LazyMan('Hank').sleep(5).eat('dinner')
LazyMan('Hank').sleepFirst(5).eat('supper')