4.1 基本类型和引用类型的值
基本类型值指的是简单的数据段如5种基本数据类型,引用类型是保存在内存中的对象。引用类型是安引用访问的,因为ECAMScript不允许直接访问内存中的位置。
4.1.1 动态的属性
定义基本类型值和引用类型值得方式为:创建一个变量并为其赋值。对引用类型的值可以为其添加或删除属性和方法,但不能给基本类型的值添加属性。
4.1.2 复制变量值
复制基本类型的值,会给变量创建一个新值。
复制对象实际上是复制的指针,两个变量指向同一个变量。
4.1.3 函数传递参数
ECMAScript中的任何函数都是按值传递的。向函数的参数传递基本类型的值时,值会被复制给一个局部变量(形参代表的变量 也可指argument[]),这个局部变量会反映在函数外部,但不会改变原变量的值,如
function add(num){ num+=10; return num; } var count=20; var result=add(count); alert(count);// 20 将count的值20传递给num,num执行num+=10,而count的值不会变。 alert(result);// 30
|
var count=20; function addNum(){ count+=10; } addNum(); alert(count);// 30. 函数通过作用域链找到外部的变量count,并改变它的值。 |
向函数传递的值时对象时:
function setName(obj){
obj.name=”Nicholas”;
obj=new Object;
obj.name=”Greg”;
}
var person=new Object();
setName(person); /*在函数内部,person和obj引用同一个对象,obj添加name性,*person也会一样。但当函数内部重写obj时,这个变量引用的*就是一个局部对象,这个局部对象在函数执行完毕后立即销毁*/
alert (person.name); //”Nicholas”
4.2 执行环境和作用域链
每个执行环境都有一个与之关联的变量对象,环境中定义的所有变量和函数都保存在这个对象中。全局变量是最外围的执行环境,其变量对象为window对象,所有的全局变量和函数都是作为window对象的属性和方法创建的。
某个执行环境中的所有代码执行完后,该环境被销毁,其中的变量和函数定义也会被销毁。
每个函数都有自己的执行环境。
当代码在一个执行环境中执行时,会创建变量对象的一个作用域链。作用域链的用途是保证执行环境有权访问所有的变量和函数,作用域两的前端是执行当前代码所在环境的变量对象。如果这个环境是函数,则将其活动对象作为变量对象,活动对象在最开始只包含arguments对象(这个对象在全局环境中不存在),作用域链下一变量对象来自外部包含对象环境,最终延续到全局环境。全局环境的变量对象始终是作用域链的最后一个对象。内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境(因为作用域链是从当期执行环境指向外层)。
例如:
var count=20;
function addNum(){
count+=10; /*函数中没有定义变量count,函数会通过作用域链找到外部的变量count,并改变它的值。*/
}zd
alert(count);/* 30. */
4.2.1 延长作用域链
使用try-catch 语句的catch块和with语句可以在作用域前端临时增加一个变量对象,该对象会在代码执行完后被移除。
var sum=new Object(); sum.a=30; sum.b=50; function build(){ var a=10; with(sum){ c=a+b; } return c;} var d=build(); alert(d); |
/*变量对象包含了sum 对象的所有属性和方法,这个变量对象被添加到了作用域的前端,变量a和b会优先使用sum中定义的。*/
//80; |
4.2.2 没有块级作用域
JS中没有块级作用域
声明变量:使用var声明的变量会自动添加到最近的环境中,对函数来说就是函数的局部变量。如果初始化时没有使用var声明,该变量会被添加到全局变量中。
为了避免错误,建议在初始化变量之前一定要声明。
查询标识符:会从作用域前端开始查询一直延续到全局变量,一旦查询到匹配的变量,搜索就会停止。如果局部变量中存在同名表示符,就不会使用位于父
4.3垃圾收集
JS具有自动垃圾收集机制
4.3.1标记清除
给不使用的值添加标记
4.3.2引用计数
计数为0时自动清除
4.3.3性能问题
4.3.4内存管理
解除引用:一旦数据不再引用,最好通过将其值设置为null来释放其引用。