js之深入理解闭包问题。
2017-10-27 09:41
495 查看
最近一段时间准备好好学习下机器学习,所以了解了很多机器学习方面的知识。抓紧补救了下自己曾经遗忘的理论知识(高数、统计学、概率论、微积分等),发现还有点吃力了,很多东西都快忘得差不多。不过,咱程序员,还是很擅长围魏救赵滴^_^。所以,我果断的选择边理论边着手老本行——编程。
目前流行的机器学习语言大抵是R语言和python了,熟悉了下R,发现简直就不该是程序员该用的,这简直就是为非专业编程人士准备的东西。大概了解了下,就放弃了。那现在选择就一个了,python。
初学python,感觉如鱼得水啊。这对把函数式编程当成工作的我来说,学起来简直游刃有余啊,瞬间被微积分概率论虐得生活不能理解的感觉一去不复返~额,貌似扯远了。前奏有点太长了,下面进入正题。
当我进入python的闭包时,看见了这么一道题。
这不就是曾经那个闭包吗?现在还记得第一次面试时,面试官问到我闭包时,我一番鬼扯然后用错误答案回答的尴尬。既然这样,我觉得有必要好好和大家分享下我心中的闭包。
闭包的特点是返回的函数还引用了外层函数的局部变量。定义听起来简单易懂,能正确应用才是关键。上个题的答案是
为什么会这样?下面我们用js的方式来处理下另外一个题目,相信能处理这个新题目,你正确处理这个题目也是很简单的事。
时间再一次回到第一次面试。面试官出了这么一道经典题目:请使用闭包输出1-100每隔一秒输出一次。额,这个问题怎么这么熟悉呢?貌似在哪里见过,一百道经典面试题还是你必须知道的十道js面试问题来着~,想了半天,就知道要用闭包,要用setTimeout。好吧,有这些就够了,既然一时想不出来,那就直接写吧!
貌似有什么不对。这个大概会输出一百个100的节奏啊~,可是哪里不对呢?找了半天,没发现,那推倒重来!既然是闭包,那不是要return函数么,那再来过。
这个么,好像没有输出值啊~,左思右想,重来。
这个像,嗯,不错,就是他了。然后愉快的将最终结果给面试官过目,面试官问了句,你确定这是我想要的结果?是的,我很确定!现在依旧记得当初的意气风发啊,年轻真好!
回来之后,把自己把程序在浏览器上跑了下,瞬间懵逼了。这不是我想要的结果啊,我想要的结果是100s!最后自己默默的在1000后面乘了个i,最终程序是这样的:
但是,为什么是这样呢?首先setTimeout是一个定时器,一个异步的定时器。什么意思呢?就是必须主程序跑完了,才开始执行它!意思就是你的for循环跑完了,才会执行setTimeout。所以如果直接输出,很明显,i的值为100.所以你会得到100个100.怎样才能保留i,让i按照我们想要的循环一下输出一下呢?那就使用闭包吧,把i传进去。这样i的值就被保留下来了,一直被
4000
内部的函数引用。所以就能输出我们想要的结果。最后为什么要乘以i呢,因为是一秒执行一次,不是过了一秒全部执行!所以~
以上就是内容的全部,如果还有不懂,请留言。我会关注的,谢谢。
选择语言问题,就是第一大难题。
目前流行的机器学习语言大抵是R语言和python了,熟悉了下R,发现简直就不该是程序员该用的,这简直就是为非专业编程人士准备的东西。大概了解了下,就放弃了。那现在选择就一个了,python。
初学python,感觉如鱼得水啊。这对把函数式编程当成工作的我来说,学起来简直游刃有余啊,瞬间被微积分概率论虐得生活不能理解的感觉一去不复返~额,貌似扯远了。前奏有点太长了,下面进入正题。
闭包?
当我进入python的闭包时,看见了这么一道题。
# 希望一次返回3个函数,分别计算1x1,2x2,3x3: def count(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fs f1, f2, f3 = count()
这不就是曾经那个闭包吗?现在还记得第一次面试时,面试官问到我闭包时,我一番鬼扯然后用错误答案回答的尴尬。既然这样,我觉得有必要好好和大家分享下我心中的闭包。
闭包是什么呢?内层函数引用了外层函数的变量(参数也算变量),然后返回内层函数的情况,称为闭包(Closure)。
闭包的特点是返回的函数还引用了外层函数的局部变量。定义听起来简单易懂,能正确应用才是关键。上个题的答案是
def count(): fs = [] for i in range(1, 4): def f(i) : def g() : return i * i return g fs.append(f(i)) return fs f1, f2, f3 = count() print f1(), f2(), f3()
为什么会这样?下面我们用js的方式来处理下另外一个题目,相信能处理这个新题目,你正确处理这个题目也是很简单的事。
时间再一次回到第一次面试。面试官出了这么一道经典题目:请使用闭包输出1-100每隔一秒输出一次。额,这个问题怎么这么熟悉呢?貌似在哪里见过,一百道经典面试题还是你必须知道的十道js面试问题来着~,想了半天,就知道要用闭包,要用setTimeout。好吧,有这些就够了,既然一时想不出来,那就直接写吧!
function closure() { for (var i = 0; i < 100; i ++) { setTimeout(function() { (function() { console.log(i); }) (i) }, 1000) } }
貌似有什么不对。这个大概会输出一百个100的节奏啊~,可是哪里不对呢?找了半天,没发现,那推倒重来!既然是闭包,那不是要return函数么,那再来过。
function closure() { for (var i = 0; i < 100; i ++) { setTimeout(function() { var foo = function(i) { return function() { console.log(i); } } foo(i) }, 1000) } }
这个么,好像没有输出值啊~,左思右想,重来。
for (var i = 0; i < 5; i++) { var a = function(v){ return function(){ console.log(v) } } setTimeout(a(i),1000) }
这个像,嗯,不错,就是他了。然后愉快的将最终结果给面试官过目,面试官问了句,你确定这是我想要的结果?是的,我很确定!现在依旧记得当初的意气风发啊,年轻真好!
回来之后,把自己把程序在浏览器上跑了下,瞬间懵逼了。这不是我想要的结果啊,我想要的结果是100s!最后自己默默的在1000后面乘了个i,最终程序是这样的:
for (var i = 0; i < 5; i++) { var a = function(v){ return function(){ console.log(v) } } setTimeout(a(i),i * 1000) }
但是,为什么是这样呢?首先setTimeout是一个定时器,一个异步的定时器。什么意思呢?就是必须主程序跑完了,才开始执行它!意思就是你的for循环跑完了,才会执行setTimeout。所以如果直接输出,很明显,i的值为100.所以你会得到100个100.怎样才能保留i,让i按照我们想要的循环一下输出一下呢?那就使用闭包吧,把i传进去。这样i的值就被保留下来了,一直被
4000
内部的函数引用。所以就能输出我们想要的结果。最后为什么要乘以i呢,因为是一秒执行一次,不是过了一秒全部执行!所以~
以上就是内容的全部,如果还有不懂,请留言。我会关注的,谢谢。
相关文章推荐
- javascript深入理解js闭包
- JS继承机制的深入理解--动态原型存在的问题与解决
- javascript深入理解js闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- 深入贯彻闭包思想,全面理解JS闭包形成过程
- 深入理解JS闭包
- 深入理解js中的闭包
- 深入理解js中的闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- [转载] javascript:深入理解js闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- javascript深入理解js闭包
- js 深入理解this指向问题
- javascript深入理解js闭包
- javascript深入理解js闭包