JS运行机制

就像我们人类为什么能生活在地球上一样,因为地球为我们提供了可以生存的条件,js运行在浏览器中,也是一样的,浏览器为js提供了运行的机制

浅分析js的运行机制:

1、当浏览器(它的内核/引擎)渲染和解析js的时候,会提供一个供js代码运行的环境,我们称这个环境为全局作用域(window  global  scope)

2、代码自上而下执行(之前还有一个变量提升阶段)

基本数据类型的存储机制:

 基本数据类型的值会存储在当前作用域(栈内存)

var a=12; 

 var b=a;

 b=13;

 console.log(a); //12

/*这里,先开辟一个空间储存12,
再声明了变量a,
然后让变量a和12相关联,
b=a的时候,是把12复制了一份赋值给b了,
这样做的目的是让 a的12,和b=a的12没有关系,
所以操作b=13的时候,改变的值不是同一个12
*/

   1)首先会开辟一个空间存储12

   2)在当前作用域中声明一个变量a

   3)让声明的变量和存储的12进行关联(把12赋值给a,赋值的操作叫做定义)

基本数据类型(值类型),是按照值来操作的:把原有的值复制一份,放到新的空间或者位置上,和原来的值没有关系

引用数据类型的存储机制:

引用数据类型的值不能直接存储在当前作用域下,因为存储的内容过于复杂,先开辟一个新的空间(理解为仓库),把内容存储到这个空间中(堆内存)

var obj={

  n:100,
  m:200      
}
/*有个空间存的 n:100,m:200 ,并且这个空间有个16进制的地址名称 AAAFFF111
把这个地址赋值给了obj
obj=AAAFFF111地址(虚拟的地址)

*/

var obj1=obj;//声明了一个变量obj1,把obj存的地址给了obj1,两个变量存的是一个空间地址,相互之前会有影响

 obj1.n=300;

console.log(obj['n']);//300 相同地址的n被改变了 

   1)首先开辟一个新的内存空间,把对象中的键值对(函数存的是字符串)依次存储起来,为了保证后面可以找到这个空间,此空间有个16进制的地址

   2)声明一个变量

   3)让变量和空间地址关联在一起(把空间地址赋值给变量)

引用数据类型操作的是空间地址,把原来空间的地址赋值给新的变量,但是原来的空间没有被克隆,还是同一个空间,这样就会出现多个变量关联的相同的空间,相互之间就会存在影响了

栈内存 && 堆内存

栈内存:提供代码运行的环境,所有的基本数据类型都会在栈内存中开辟位置存储

堆内存:存储引用数据类型的值一个作用,对象存的是键值对,函数存储的是代码字符串

堆内存的释放:

1、放堆内存没有被任何变量或者其他东西占用,浏览器会在空闲的时候,自主的进行内存回收,把所有不被占用的堆内存销毁掉(谷歌浏览器的释放内存机制)

2、在创建内存的时候,在每个内存上贴一个标签(内存占用计数器),每被占用一次就记一次,不被占用了就减一次(IE浏览器的释放内存机制)

栈内存销毁:

一般情况下,当函数执行完成,所形成的私有作用域(栈内存)都会自动释放掉,特殊不销毁的情况:

   1)函数执行完成,某些内容被内存以外的变量占用了

   2)全局栈内存只有在页面关闭的时候才会释放掉

如果当前栈内存没有释放,之前存储的基本值也不会被释放,能够一直保存下来

堆内存销毁:

变量=null ;变量指向空对象指针,浏览器会在空闲的时候自主释放堆内存

总结:当js代码在浏览器中运行的时候,浏览器会开辟一个栈内存(全局作用域),基本数据类型的值会直接在栈内存中开辟空间,多个变量之间的值不会有关系,引用数据类型会开辟一个新的堆内存来储存,并分配一个16进制的地址,多个引用数据类型的变量可以存储同一个空间地址,可以相互更改同一个地址的内容,不管 是基本数据类型还是应用内数据类型,赋值操作都是先有值再有变量,再把值赋值给变量;

 思考题:

var ary1=[1,2];
 var ary2=ary1;
 ary2[0]=6;// 6,2
 ary2=[3,4];//这里把ary2重新赋值了一个新的堆内存
 ary2[1]=5;//3,5
 ary1[1]=0;//6,0
 console.log(ary1,ary2);//[6,0]   [3,5]

 

posted @ 2019-08-29 17:37  欣欣向荣998  阅读(168)  评论(0编辑  收藏  举报