当前位置: 首页 > Web前端 > HTML

JS变量和执行环境

时间:2023-03-28 11:09:22 HTML

1.数据类型1.1基本类型和引用类型的取值在JavaScript中,变量的数据类型分为基本类型和引用类型。基本类型是指那些简单的数据段,包括Boolean、Number、String、Undefined、Null、Symbol。基本数据类型直接按值访问,可以操作存储在变量中的实际值。引用类型的值是一个存储在内存中的对象。JavaScript不能直接访问内存中的位置,而是通过指针将变量与内存中的对象关联起来。因此,我们在操作对象时,实际上是在操作对象的引用。1.2栈内存和堆内存为了更深入的理解JS变量的基本类型和引用类型的区别,我们还需要了解JS变量的值在内存中是如何存储的。1.2.1栈内存栈是一种具有先进后出和后进先出特点的数据结构。就像羽毛球筒一样,只有一个端口(即出口和入口),先进入的球只能最后取出:如上图,堆叠顺序:1、2,3,出栈顺序:3,2,11.2.2栈内存中的数据存储栈内存用于存储基本类型的变量或变量指针,例如:varnum1=3;变量num1在内存中的存储形式是:对于基本类型的变量,当我们进行复制操作时,比如这个例子:varnum1=3;增值税num2=num1;这时候JS会创建一个新值,并将新值赋值给一个新的变量。内存中的变量对象表示为:变量num2得到的是一个全新的值,与变量num1中的值无关。1.2.3堆内存堆内存不同于栈内存,变量值的存储没有规律可循。1.2.4堆内存中的数据存储堆内存用于存储对象类型的变量值,对象的内容和大小也会随时发生变化。这时,变量对象中的变量存储了一个指向堆内存中对象的指针。由于这种引用关系的存在,对象也被称为引用类型。例子:varnum1=3;varobj={a:1}当我们复制对象类型的值时,实际上复制的是对象的指针,所以两个变量指向同一个对象,例如:varobj1={a:1}varobj2=obj1;在内存中表现为:此时修改变量obj1的属性等同于修改变量obj2,例如:varobj1={a:1};vatobj2=obj1;obj1.b=2;alert(obj2.b);//21.3包装对象对于引用类型的值,我们可以给它添加属性和方法,也可以改变和删除它的属性和方法:varperson=newObject();person.name='Ian';alert(person.name);//'Ian'但是,我们不能向原始值添加属性,尽管这样做不会导致错误:varname='Ian';name.age=29;alert(name.age);//undefined我们可能听说过一种说法,基本类型的值没有属性或方法。有意思的是,上面提到的给基本类型的值添加属性的操作是不会报错的,而且我们还可以读取一些基本类型的值,比如我们可以读取的值的length属性字符串类型:varname='Ian';名称.长度;//3那么基本类型值的属性从何而来呢?其实我们在操作基本类型值的属性的时候,JS会创建一个临时的包装对象,而我们操作的其实是这个包装对象的属性,这个包装对象用完了会立马销毁。在上面的示例中,name.length的length属性实际上来自包装器对象。varname='Ian';name.length;varnameObj=newString(name);//包装对象nameObj.length;//3由于wrapper对象用完即销毁的特性,我们不修改基本类型值的属性是“invalid”:varname='Ian';name.length=4;name.length;//3在上面的例子中,当我们再次读取name.length时,实际上是创建了一个新的wrapper对象,读取新wrapper对象的length属性。2.执行环境执行环境(也叫环境)是JavaScript的一个重要概念。执行环境定义了变量或函数可以访问的数据。每个执行环境都有一个关联的变量对象,它存储了当前执行环境中定义的所有变量和函数。2.1全局执行环境JS代码执行时最外层的执行环境称为全局执行环境。由于宿主环境不同,代表全局执行环境的对象也不同。在网络浏览器中,window对象被用作全局执行环境,全局执行环境变量和函数被声明为window对象的属性和方法。2.2执行环境栈函数也有一个执行环境。当函数开始执行时,函数执行环境会被压入执行环境栈。函数执行完成后,执行环境栈会弹出函数环境,把主导权交给上层。环境。我们用一段代码来展示执行环境栈的变化过程:varouterName='Ian';functionchangeName(){varinnerName='Jack';outerName=innerName;}alert(outerName);//'Jack'处于初始状态接下来,执行环境栈是这样的:当函数changeName开始执行时,将函数的环境压入环境栈:当函数changeName执行完成时,环境被弹出环境栈并销毁(环境栈回到上一步的状态),其中存储的变量和函数的定义也被销毁。全局环境只有在程序退出时,网页或浏览器程序在网络浏览器中关闭时才会被破坏。JS的执行机制还引出了另一个重要的概念——作用域链。2.3作用域链JS代码在进入一个新的执行环境时会创建一个作用域链(scopechain),用于指定访问当前执行环境的变量或函数的访问顺序。作用域链由执行环境的变量对象组成。如果是函数环境,函数的活动对象作为变量对象。作用域链的前端始终是当前执行环境的变量对象,上层变量对象来自上层执行环境,直到全局环境的变量对象。当我们访问一个变量时,我们会先在当前变量对象中查找,如果找不到,就在作用域链中向上查找,直到返回变量的值或者报错(变量没有声明).让我们通过一个例子来理解这个结构:varouterName='Ian';functionchangeName(){varinnerName='Jack';外名=内名;函数alertName(){alert(outerName);//'杰克'}}alert(innerName);//UncaughtReferenceError:innerNameisnotdefined上面代码中,函数可以访问外部定义的变量outerName,但是函数内部定义的变量innerName在全局环境下是访问不到的。当代码进入alertName执行环境时,作用域链如下图所示:3.总结在JavaScript中,变量的数据类型分为基本类型和引用类型。它们具有以下特点:基本类型的值大小是固定的,存放在栈内存中,当复制基本类型的值时,会创建该值的副本;引用类型的值是一个对象,存放在堆内存中,变量保存着对象的引用。复制引用类型的值时,复制的是Object引用,两个变量都指向同一个对象;全局执行环境和函数执行环境;当进入一个新的执行环境时,创建一个作用域链来指定访问当前执行环境的变量或函数的访问顺序;函数局部环境可以访问父(直到全局)环境的变量,而全局(父)环境不能访问函数的局部变量;