第四章——变量、作用域、内存问题
变量的两种基本类型
- 基本数据类型
简单的数据段 五种基本类型的数据是按值传递的 - 引用类型
包含多个值构成的对象 对象是按引用访问的
我们只能给引用类型值动态添加属性,基本类型值是不能添加属性的。
对于基本类型和引用类型的复制问题,代码展示:
基本类型
var num=1;
var num1=num;
//将num1赋予给num2,但实际上改变num1的值不会影响num2,两个变量是相互对立的
引用类型
var obj1=new Object();
var obj2=obj1;
obj1.name=’sdfsdf’;
alert(obj2.name)//’ sdfsdf’
//引用类型复制的是一个指针,但两个指针指向同一片内存区域,所以改变其中一个,另一个会被影响
函数的参数是按值传递的,基本数据类型,直接按值传递,没有疑义。而引用类型当成参数传递时,储存对象的变量是按值传递,而变量指向的对象的指针是引用传递。
function setName(obj){
Obj.name=’yyy’
}
var person=new Object();
setName(person);
alert(person.name) //’yyy’
//而person变量就是按值传递,但是所指向的对象是同一个对象,(函数内部obj按引用传递)
检测基本类型数据:
用
typeof
返回string number Boolean …… 对于对象和null 返回 object
检测对象引用类型数据:
*用
instanceof
code: person instanceof Object colors instanceof Array 返回真假
每个执行环境都有一个与之关联的变量对象。 全局环境被认为是window对象,window对象只有在应用程序退出,才会被销毁,其中的变量和函数定义也随之销毁
作用域链:
作用域链的前端始终是当前执行代码所在环境的变量对象,最后一个对象就是全局执行环境的变量对象window,
简单来说是一条访问次序由里往外的链。
延长作用域链:
可以用with语句和catch语句来延长作用域
With语句接收的对象会被添加到作用域链的前端并在代码执行完成后移除,而在其中添加的新变量还是属于with语句所在的执行环境,而不属于接收对象的。但在其中改变接受对象已有的变量的值,则接收对象变量值就改变了
Catch则会创建一个新的变量对象
垃圾收集的两种方式: 1、标记清除2、引用计数
引用计数存在问题的就是,循环引用的变量无法清除
优化内存占用的最佳方式,就是为执行中的代码只保存必要的数据,一旦代码不再有用,将值设为null来释放引用,这种做法叫做解除引用