scope(域),js的闭包

scope(域)


这两个概念必需一起理解,闭包是讲编译方式,scope是讲闭包的原理 ,相辅相成的。
由于js有预编译的阶段,然后再是执行阶段。在预编译阶段,会根据var和function关键字找到声明的变量和函数,然后抽出来。在执行阶段,根据代码定义赋值的地方初始化var声明的变量,在调用函数时,会创建新的scope(域),scope存在的内容就是预编译阶段抽出的var声明和变量和function声明的函数,注意保存的是引用,里面的内容可能会被代码修改。

函数在定义的时候就会创建一个scope,保存当前环境下的数据,在执行函数时,内部会创建一个新的scope,这个scope内的数据是根据代码的执行不断变化的。这个新的scope当前执行的函数可以有一份,如果函数返回另一个函数,那另一个函数在定义的会创建一个scope。
总结一句话,函数定义时,会根据当前环境创建一个scope并保持关系,在函数执行时创建一个新的scope,2个scope是父子依赖关系,在JavaScript中所有的域都是并且只能是被函数域(function scope)所创建,它们不能被for/while循环或者if/switch表达式创建

第一个scope内部数据为{name:underfined, test1:function(){...}}由于执行第一个test1()时,name还没初始化,所以为underfined),第二个scope是函数体内部scope为{c=3},2个scope构建scope链,查找变量,先从内部开始找,找不到向上游找,直到找到全局scope。

理解scope要点
-函数在定义时,会生成一个scope
-函数在执行时,会创建一个新的scope
也叫做本地scope,同时创建一个链接向上父scope,scope域内维护的数据是预编译时筛选的var和function声明的东西。不是环境执行时上下文环境变量
- scope可以用于创建函数时保存函数定义时一些数据

this变量

对于this,我们可以理解为:特殊的Scope引用变量,其指向当前函数的执行环境Scope(并不是定义时的Scope)
 

可以使用apply改变执行上下文时环境,比如doit.apply(funderfined, "666")

闭包

闭包(closure)是Javascript语言的一个难点,也是它的特色,很多高级应用都要依靠闭包实现
我觉得闭包就出现就是为了保存执行环境时一些变量数据
有权访问另一个函数作用域内变量的函数都是闭包.

闭包就是将函数内部和函数外部连接起来的一座桥梁

闭包就是能够读取其他函数内部变量的函数

闭包的用途

1一个是前面提到的可以读取函数内部的变量

2另一个就是让这些变量的值始终保持在内存中(会一直在内存中,这也是闭包的缺点,容易造成内存泄漏)

我们一般喜欢通过一个函数返回另一个函数的闭包形势,将外部数据变成函数的局部变量,然后返回的函数在定义时创建一个scope,scope保存有这个局部变量值,这样一来,这个返回的函数就会一直保存传入的数据。

使用闭包的注意点

1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。

2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值

闭包有3个特性:

①函数嵌套函数

②函数内部可以引用函数外部的参数和变量

③参数和变量不会被垃圾回收机制回收

闭包的步骤:

1.函数内部嵌套子函数,

2.子函数得到父函数的值。

3.把内层函数返回出去

你可能感兴趣的:(前端)