分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 教程案例

js变量的生命周期

发布时间:2023-09-06 02:30责任编辑:胡小海关键词:js

变量的生命周期

 

1.声明

全局变量:全局声明的变量
局部变量:函数内声明的变量,函数参数


声明局部变量的时候必须用var,否则产生的是全局变量

1 scope = "global";2 function checkscope2() {3 ????scope = "local";4 ????myscope = "local";5 }6 checkscope2();7 console.log(scope);//输出local,全局变量被修改8 console.log(myscope);//输出local,全局命名空间被搞乱了

使用var声明的变量是不可配置的,即无法通过delete运算符删除

 
1 var truevar = 1;//不可配置的全局变量2 fakevar = 2;3 this.fakevar2 = 2;4 delete truevar;//出错5 delete fakevar;//执行成功6 delete this.fakevar2;//执行成功

在函数内部中局部变量会遮盖同名的全局变量

 
1 var scope = “global”;//声明一个全局变量2 function checkscope(){3 ????var scope = “local”;//声明一个同名的局部变量4 ????console.log(scope);//输出”local”5 }
 

2.变量提升(变量声明提前)

即函数中声明的所有变量都被“提前”至函数体的顶部,这步操作是在代码开始运行之前的JavaScript引擎预编译时执行的。 
例:

 
1 var scope = “global”;2 function f(){3   console.log(scope);//输出”undefined”,而不是”global”4   var scope = “local”;//变量在这里声明且赋初值,但变量本身在函数体内任何地方均是有定义的5   console.log(scope);//输出”local”6 }

实际上,上述的代码等价于:

1 var scope = “global”;2 function f(){3   var scope4 ???console.log(scope);//输出”undefined”,而不是”global”5 ???scope = “local”;//变量在这里声明且赋初值,但变量本身在函数体内任何地方均是有定义的6 ???console.log(scope);//输出”local”7 }
 

3.全局变量与局部变量的作用域

全局变量:当声明一个全局变量时,实际上是定义了全局对象window的一个属性,在任何地方都可以对其进行访问

局部变量:局部变量在声明它的函数体内以及其所嵌套的函数体内是有定义的。

作用域链:

 
 1 var color = "blue"; 2 function changeColor(){ 3 ????var anotherColor = "red"; 4 ????function swapColors(){ 5 ????????var tempColor = anotherColor; 6 ????????anotherColor = color; 7 ????????color = tempColor; 8 ????????// 这里可以访问 color、anotherColor和tempColor 9 ????}10 ????//这里可以访问color和anotherColor,但不能访问tempColor11 ????swapColors();12 }13 // 这里只能访问 color changeColor(); ???????

矩形表示特定的执行环境 
其中,内部环境可以通过作用域链访问所有的外部环境,但 外部环境不能访问内部环境中的任何变量和函数。。每个环境都 可以向上搜索作用域链,以查询变量和函数名;但任何环境都不能通过向下搜索作用域链而进入另一个执行环境。

对于上面的例子而言,其作用域链中包含 3个对象:swapColors()的变 量对象、changeColor()的变量对象和全局变量对象。swapColors()的局部环境开始时会先在自己的 变量对象中搜索变量和函数名,如果搜索不到则再搜索上一级作用域链,即changeColor()的作用域链 

作用域链的延长 :

 
 1 var outer = { 2 ????value : "outer", 3 ????index : 0 4 } 5 function test() { 6 ????var inner = "inner"; 7 ????with(outer){//将outer对象添加到此作用域,可以在其中直接使用其方法和属性 8 ????????value = inner; 9 ????}10 }11 test();12 console.log(outer.value);//输出"outer"

除了with,我们还可以使用catch延长作用域链

5.垃圾回收

标记清除(常用):

工作原理:是当变量进入环境时,将这个变量标记为“进入环境”。当变量离开环境时,则将其标记为“离开环境”。标记“离开环境”的就回收内存。

工作流程:

1.垃圾回收器,在运行的时候会给存储在内存中的所有变量都加上标记。

2.去掉环境中的变量以及被环境中的变量引用的变量的标记。

3.再被加上标记的会被视为准备删除的变量。

4.垃圾回收器完成内存清除工作,销毁那些带标记的值并回收他们所占用的内存空间。

引用计数:

工作原理:跟踪记录每个值被引用的次数。

工作流程:

1.声明了一个变量并将一个引用类型的值赋值给这个变量,这个引用类型值的引用次数就是1。

2.同一个值又被赋值给另一个变量,这个引用类型值的引用次数加1.

3.当包含这个引用类型值的变量又被赋值成另一个值了,那么这个引用类型值的引用次数减1.

4.当引用次数变成0时,说明没办法访问这个值了。

5.当垃圾收集器下一次运行时,它就会释放引用次数是0的值所占的内存。

弊端:在循环循环引用中变量的引用次数不会为零则变量不会被回收

 
1 function test(){2 ????var a={};3 ????var b={};4 ????a.prop=b;//a的引用次数为25 ????b.prop=a;//b的引用次数为26 }

而为了解决这种问题,可以显性地切断引用,即将变量的值设为null

现在大部分的浏览器都是采用标记清除的垃圾回收机制,而IE的BOM和DOM中的对象是以引用计数方式进行垃圾回收的COM对象的形式存在的,所以会有导致变量不能被回收的现象。但是在IE9之后就取消了COM对象的形式。

js变量的生命周期

原文地址:https://www.cnblogs.com/wament/p/10271091.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved