闭包, 定时器

  • 什么是闭包? 有什么作用
    • 闭包的形成
      在高级程序设计3中对于闭包的定义是这样的
      <blockquote>有权访问另一个函数作用域中的变量的函数。</blockquote>
      在Wikipedia中的定于是这样的
      <blockquote>引用了自由变量的函数。</blockquote>
      一开始,我对这样的抽象概念很模糊,但是当我理解了闭包之后,我又认为这样的定义是简介而有力的,如果从理解闭包的定义来说,可以认为JS中的所有函数都是闭包,因为每个函数都能访问到全局作用域的自由变量
var a = 1
function fn() {
    console.log(a)
}
fn()

在这个例子中,fn可以访问了全局变量a,这个函数就叫做闭包,当然,这只是从理解的角度来说,实际上这样的全局作用域下的闭包是没意义的,因为全局的变量对象不会被销毁。在函数内部的闭包可以在chrome的开发者工具看到


2016-08-19_154334.png

要理解闭包的和闭包的作用,就要从作用域链的形成开始,通过下面的例子来说明

var a =2
function fn() {
    var a = 1
    function fn2() {
        console.log(a)
    }
    fn2()
}
fn()

因为js是词法作用域,当函数fn声明的时候,就会预先包含全局作用域链,然后放在fn.Scope中,[[Scope]]是一个只有语言内部才能访问的属性,当函数fn被调用的调用的时候,会创建一个执行环境,执行环境里面有两个东西,一个是变量对象在函数内部又叫活动对象,一个是作用域链,作用域链的形成就是复制fn.Scope里面的变量对象,然后推入当前的活动对象。当fn执行完的时候,本来fn执行环境的变量对象和作用域链都会销毁,但是现在只有作用域链销毁了,变量对象却没有销毁,因为内部的函数fn2的作用域链在引用这fn的变量对象。因为fn2的作用域链里面包含fn的变量对象,所以可以访问到fn的变量,所以也就形成了闭包。
- 闭包的缺点
1. 在IE9之前因为使用不同的垃圾收集机制会导致循环引用会造成内存泄漏
2. 闭包会携带包含函数的作用域,所以会比其他函数占用更多内存,过度使用闭包会造成内存占用过多
- 闭包的用法
其实保存变量现场,封装私有变量都是对闭包特性的利用,并不是闭包的定义,不要混淆
1. 保存变量现场,主要利用了js函数传递参数的方式是按值传递

!function() {
    var arr = []
    for (var i = 0; i < 5; i++) {
        arr[i] = function () {
            alert(i)
        }
    }
    arr[1]()//5
}()

本来的打算应该数字的每一项都是一个函数,可以打印出每一项的索引,但是因为所访问的i是外部函数的,当循环完以后,i已经累加到5了,所以无论多少输出当然是5,我们可以利用js函数传递是按值传递的方式来改造这个数组

!function() {
    var arr = []
    for (var i = 0; i < 5; i++) {
        arr[i] = function (n) {
            return function () {
                alert(n)
            }
        }(i)
    }
    arr[1]()//5
}()

改造后的函数输出就是1,主要利用按值传递参数和闭包
2. 封装私有变量
有时候我们常常需要隐藏一些数据,而仅仅暴露一些接口供外部使用,起到封装的效果,这时候就可以利用闭包

var Car = (function () {
    var speed = 0
    return {
        setSpeed: function (s) {
            speed = s
        },
        getSpeed: function () {
            return speed
        }
    }
})()
Car.setSpeed(30)
Car.getSpeed()

这就封装了一个汽车对象,其中是speed私有的变量,只能通过我们提供的接口setSpeed和getSpeed来访问到

  • setTimeout 0 有什么作用
    setTimeout表示的是超时调用,setTimeout可以接受多个参数,表示过延迟多长时间再执行回调函数
    • 第一个参数表示回调函数,可以是一个字符串或者是一个函数名,推荐使用函数名,因为字符串会导致一定的损耗和安全问题
    • 第二个参数表示延迟的时间,单位是ms毫秒,因为js是单线程的解释器,所以一次只能执行一段代码,为了控制要执行的代码,就有一个任务队列,这些任务就会按照他们添加到任务队列的顺序执行,延迟的时间表示再过多少ms才把当前任务添加到任务队列,如果队列前面没有任务,当前任务就会立即执行,如果队列前面有任务,就要等到前面的任务执行完之后再执行
    • 第三个和后面的参数表示参数回调函数的参数
      setTimeout(f,0)表示的就是尽快的执行函数f,他的作用可以调整时间的发生顺序,例如在开发中,某个事件发生在子元素,然后冒泡到父元素,即子元素的回调函数会比父元素的回调函数先执行,通过setTimeout(f,0)我们就可以让子元素的回调函数排在队列后面,从而让父元素的回调函数先执行
      参考:
      定时器-阮一峰
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容

  • 什么是闭包? 有什么作用闭包:函数对象可以通过作用域链相互关联,函数体内部的变量可以保存在函数的作用域内。 上述代...
    coolheadedY阅读 719评论 0 0
  • 问题 一、什么是闭包? 有什么作用? 闭包闭包就是能够读取其他函数内部变量的函数。在javascript中,只有函...
    婷楼沐熙阅读 572评论 0 0
  • 问答 1.什么是闭包? 有什么作用? 闭包 简而言之 就是让函数外部可以访问函数内的局部变量,就是将函数内部和函数...
    我是小韩阅读 301评论 1 0
  • 1.什么是闭包? 有什么作用 定义:闭包就是嵌套在函数里面的内部函数,并且该内部函数可以访问外部函数中声明的所有局...
    饥人谷区子铭阅读 900评论 0 2
  • “那时我们有梦,关于文学,关于爱情,关于穿越世界的旅行。”北岛所说的“那时”大概就是我们这样一个年纪吧,对于自...
    惜爱汐阅读 365评论 0 4