TIL icon indicating copy to clipboard operation
TIL copied to clipboard

惰性函数

Open xiaohesong opened this issue 6 years ago • 7 comments

今天看到一篇文章中有提到 惰性函数 。感觉很新奇,去查了下,发现就是自己调用自己。

可以让你只在第一次的时候调用你需要处理的函数,后面可以直接使用函数。

var foo = function() {
  console.log('你会发现我只出现一次哦,不管你调用几次')
  foo = function() {
    console.log('嘻嘻,我出现了哦')
  }
  foo()
}

foo() // 你会发现我只出现一次哦, 不管你调用几次; 嘻嘻,我出现了哦
foo() //嘻嘻,我出现了哦

还挺有意思的,留下个问题,你觉得这个是因为啥,为啥会出现上面的情况?

xiaohesong avatar Nov 26 '18 07:11 xiaohesong

因为上面第三行的时候,把foo函数重写了,所以未来只会有 “嘻嘻,我出现了哦”

YuYuBei avatar Dec 07 '18 02:12 YuYuBei

试了下,这样就不行。

var foo = function() {
  console.log('你会发现我只出现一次哦,不管你调用几次')
  var foo = function() {
    console.log('嘻嘻,我出现了哦')
  }
  foo()
}
foo()
foo()

😢

medeen avatar Dec 07 '18 10:12 medeen

试了下,这样就不行。

var foo = function() {
  console.log('你会发现我只出现一次哦,不管你调用几次')
  var foo = function() {
    console.log('嘻嘻,我出现了哦')
  }
  foo()
}
foo()
foo()

😢

这是因为你在第三行的时候,重新var了一下foo(新foo),这个新foo的作用域是在范围比较大的foo(旧foo)里面,所以不能把旧foo进行重新赋值为一个新foo,这样每次运行的时候,都是存在两个不同的foo

YuYuBei avatar Dec 07 '18 11:12 YuYuBei

@YuYuBei 👍 @medeen 可以看下这个文章js的执行上下文 对js的执行有个了解

xiaohesong avatar Dec 07 '18 11:12 xiaohesong

@xiaohesong 三克油,这些都是你自己翻译的吗?

YuYuBei avatar Dec 10 '18 07:12 YuYuBei

@YuYuBei 嗯,看到一些不错的会记录下来

xiaohesong avatar Dec 10 '18 07:12 xiaohesong

class Man {
    constructor(name) {
        this.name = name
        console.log(`Hi! This is ${name}`)
        this.queue = []
        setTimeout(() => {
            this.next()
        }, 0)
    }

    toQueue(fn, isFirst) {
        if(isFirst) {
            this.queue.unshift(fn)
        } else {
            this.queue.push(fn)
        }
        return this
    }

    next() {
        const fn = this.queue.shift()
        fn && fn()
    }

    eat(food) {
        const eater = () => {
            console.log(`Eat ${food}`)
            this.next()
        }
        this.toQueue(eater)
        return this
    }

    sleepFirst(time) {
        this.sleep(time, true)
    }

    sleep(time, isFirst) {
        const sleeper = () => {
            setTimeout(() => {
                console.log(`Wake up after ${time}`)
                this.next()
            }, time * 1000)
        }
        this.toQueue(sleeper, isFirst)
        return this
    }

}

const LazyMan = (name) => new Man(name)

LazyMan('小明').eat('午餐').sleep(2).eat('晚餐').sleepFirst(3);

xiaohesong avatar Sep 27 '23 09:09 xiaohesong