图形Javascript——作用域、闭包、闭包

图形Javascript——作用域、闭包、闭包
行动的范围是什么

范围是一个规则,这是在代码编写阶段确定,并指定要访问的变量和函数的范围。全局变量具有全局范围,而局部变量具有局部scope.js不是块级范围的语言(包括如果和其他语句的代码块或支撑代码分离的支撑块不形成局部范围),所以JS的局部范围内形成支撑的唯一功能是在代码块的形式定义,功能范围。

什么是一连串的行动

范围链是范围规则的实现。通过实现范围链,变量可以在其作用域中访问,函数可以在其作用域中调用。

范围链是一个单向访问列表,这个列表的每个节点都是执行变量对象(代码执行是活动对象),单向链表头(它可以是第一个访问节点)当前正在执行函数调用变量对象(活动对象)。尾巴永远是全球活动的对象。

形成一系列的行动

从一段代码的执行中,我们观察范围链的形成过程。
功能fun01(){
console.log(我fun01…;
fun02();
}
功能fun02(){
console.log(我fun02…);
}
Fun01 ();
数据访问过程

如上图所示,当程序访问一个变量时,根据范围链的单向访问特性,它首先在头节点的AO中找到,然后不搜索下一个节点的AO,最多找到全局AO。在这个过程中发现,没有发现错误的未定义。

延长行动链

从上面的范围链形式可以链上看到每个节点在函数被调用到当前函数链头Unshift AO,和节点形式有一种方法可以延长作用域链,我们想插入一个作用域的对象的作用域链头。有两种方式为了延长诉讼链:

1.with声明
功能fun01(){
用(文档){
console.log(我fun01和我在文件范围…)
}
}
fun01();
2.try-catch catch块的语句
功能fun01(){
{试
console.log(有例外发生…)
} catch(e){
console.log(E)
}
}
fun01();
PS:个人觉得用语句没用得多,而且也需要试用catch。个人不多用这两种东西,但在这部分整理的过程中,一点点不成熟的性能优化提示在范围链层次上都在萌芽。

一个行动链对性能优化的不成熟建议

1。减少可变行动链的接入节点

在这里,我们定义了一个名字叫查找距离,这表明该程序访问一个非在行动链定义变量节点数量。因为如果没有变量是在当前节点的发现,它跳到下一个节点是否有下一个节点的查找变量的时间。搜索距离,越跳越和判断动作要做,的资源开销较大,从而影响性能。这种性能差距可能会带来少量的变量查找操作,不会带来太多的性能问题,但如果多个变量查找进行性能对比是很明显的。
(函数({){)
console.time()
var find = 1 find变量需要在4范围链节点中搜索
功能乐趣(){
功能很有趣(){
无功funnv = 1;
无功funnvv = 2;
功能funnn(){
var I=0
当(i = 100000000){
如果(发现){
我+ +
}
}
}
funnn()
}
(有趣)
}
(有趣)
Console.timeEnd()
})

(函数(){())
console.time()
功能乐趣(){
功能很有趣(){
无功funnv = 1;
无功funnvv = 2;
功能funnn(){
var I=0
var查找= 1,仅在当前节点搜索中查找此变量
当(i = 100000000){
如果(发现){
我+ +
}
}
}
funnn()
}
(有趣)
}
(有趣)
Console.timeEnd()
})
实验是在1亿个查找操作的Mac浏览器的Chrome浏览器下完成的。

实验结果:前者运行5次与85.599ms平均时间,后者是5次63.127ms平均时间。

2。避免在范围链上对节点AO变量过度定义

性能问题的主要原因是对变量的过度定义,这主要是由于变量过程的判断开销较大。
(函数(){())
console.time()
功能乐趣(){
功能很有趣(){
无功funnv = 1;
无功funnvv = 2;
功能funnn(){
var I=0
var查找= 10
用(文档){
当(i = 1000000){
如果(发现){
我+ +
}
}
}
}
funnn()
}
(有趣)
}
(有趣)
Console.timeEnd()
})
在Mac Pro Chrome浏览器中,我们做实验,做100万个搜索操作,并使用文档扩展范围链。由于文档具有多个可变属性,所以可以在多变量范围链节点下测试性能差异。

实验结果:5次平均耗时558.802ms,如果文件被删除,5次平均耗时0.956ms。

当然,这两个实验是在我们假设的极端情况下进行的,其结果仅供参考

关于闭包

1。什么是壁橱

函数对象可以通过范围链相互关联。在函数体的数据(变量和函数的声明)可以存储在函数的范围,这是在计算机科学文献要求关闭。在这个函数的功能是隐藏在数据链,它看起来像一个函数,数据封装。从技术的角度来看,JS功能:功能全部关闭所有对象,所有的行动链相关,在功能的数据都存储在功能范围。

2的几种实现。关闭

实现它的方法是在函数B中定义函数A,当函数A执行时,它访问函数B中的变量对象,然后B是一个闭包:
在上述两图所示,这是查看关闭Chrome浏览器下的方式。这两种方式常见的方式是,外部有一个功能outerfun(),它定义了内部功能innerfun()在外部函数和内部函数可以访问外部数据的功能。不同的是,innerfun第一种方式称为()(),在outerfun声明和在同一个执行上下文调用,innerfun二类型(outerfun)()是在外面打电话,不在同一个表,称为一个执行上下文。二是特征js使用闭包。闭包的特性可以用于访问其他执行上下文中的函数内部数据。

我们使用的一种比较常见的方法是:
关闭案例
功能outerfun(){
无功outerv1 = 10
功能outerf1(){
console.log(我outerf1…)
}
功能innerfun(){
无功innerv1 = outerv1
outerf1()
}
返回innerfun / /返回innerfun()内部函数
}
var fn = outerfun(收益)/收回innerfun(功能)
(FN) / /执行内部功能innerfun()来
此时,它的范围链就是这样的:
3的好处和用途。关闭

js的垃圾回收机制大致可以概括如下:如果执行上下文完成,有没有其他的参考背景,然后执行上下文的流行是调用堆栈,并在它的数据等待垃圾回收。当我们仍引用通过关闭其他的执行环境数据被引用的数据将不会被垃圾收集。就像在上面的代码中的outerv1,当我们仍要求参考outerv1全球化语境中通过调用innerfun(),outerfun执行后,outerv1不会被垃圾收集,但存储在存储器中。此外,outerv1看不一个outerfun私人内部变量吗除了innerfun(),我们无法访问outerv1的意愿。所以,综上所述,这衣柜的使用情况可以概括为:

(1)变量持久性。

(2)在功能对象中有更好的封装和内部数据私有化。

在可变持久性方面做一个栗子:

我们假定一个函数被写入执行一个类似于id自增的函数,或者当一个需求被写入时调用计算函数的函数。
var计数= 0
功能countfun(){
返回计数+
}
这个写的功能,但计数是暴露,可能会篡改其他代码。这一次的青年壁橱将写这一点:
功能countfun(){
var计数= 0
返回函数(){
返回计数+
}
}
创建一个countfun()
(一)
这样,计数不会被无意中篡改,函数调用被添加到计数1一次,如果每次调用一个函数,就会创建一个新的执行上下文,这个计数的安全性如下:
功能countfun(){
var计数= 0
返回{
计数:函数(){
计数+ +
},
重置:函数(){
数= 0
},
printcount:函数(){
console.log(计数)
}
}
}
创建一个countfun()
var b = countfun()
a.count()
a.count()
B.count()
B.reset()
a.printcount(2) / /打印:因为a.count()调用两次
(b.printcount) / /打印:0(b.reset)因为电话
以上是闭包提供的变量持久性和封装性的体现。

4。注意关闭的事项

因为闭包中的变量不会像其他正常变量那样被垃圾收集,而是留在内存中,所以闭包的使用会导致性能问题。

以上是本文的全部内容,希望本文的内容能给大家的学习工作带来一定的帮助,同时也希望能给予更多的支持
免责声明:本网信息来自于互联网,目的在于传递更多信息,并不代表本网赞同其观点。其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,并请自行核实相关内容。本站不承担此类作品侵权行为的直接责任及连带责任。如若本网有任何内容侵犯您的权益,请及时联系我们,本站将会在24小时内处理完毕。
相关文章
返回顶部