// 有些语句可以在作用域链的前端临时增加一个变量对象,该变量对象会在代码执行后被移除; // with语句和try-catch语句;这两个语句都会在作用域链的前端添加一个变量对象; // with语句:会将指定的对象添加到作用域链中; // catch语句:会创建一个新的变量对象,其中包含的是被抛出的错误对象的声明; function buildUrl(){ var qs = '?debug=true'; with(location){ // with语句接收的是location对象,因此变量对象中就包含了location对象的所有属性和方法; var url = href+qs; // 而这个变量对象被添加到了作用域链的前端; }; return url; }
8.没有块级作用域
// 块级作用域:表示诸如if语句等有花括号封闭的代码块,所以,支持条件判断来定义变量; if(true){ // if语句代码块没有局部作用域; var box = 'lee'; // 变量声明会将变量添加到当前的执行环境(在这里是全局环境); } alert(box); for(var i=0; i<10; i++){ // 创建的变量i即使在for循环执行结束后,也依旧会存在与循环外部的执行环境中; var box = 'lee'; } alert(i); alert(box); function box(num1,num2){ var sum = num1+num2; // 此时sum是局部变量;如果去掉var,sum就是全局变量了; return sum; } alert(box(10,10)); alert(sum); // sum is not defined;访问不到sum; // PS:不建议不使用var就初始化变量,因为这种方法会导致各种意外发生; // 一般确定变量都是通过搜索来确定该标识符实际代表什么;搜索方式:向上逐级查询; var box = 'blue'; function getBox(){ return box; // 此时box是全局变量;如果是var box='red',那就变成局部变量了; } alert(getBox()); // 调用getBox()时会引用变量box; // 首先,搜索getBox()的变量对象,查找名为box的标识符; // 然后,搜索继续下一个变量对象(全局环境的变量对象),找到了box标识符; // PS:变量查询中,访问局部变量要比全局变量更快,因为不需要向上搜索作用域链;
二 内存问题
// JS具有自动垃圾收集机制,执行环境会负责管理代码执行过程中使用的内存;它会自行管理内存分配及无用内存的回收; // JS最常用的垃圾收集方式就是标记清除;垃圾收集器会在运行的时候给存储在内存中的变量加上标记; // 然后,它会去掉环境中正在使用的变量的标记,而没有被去掉标记的变量将被视为准备删除的变量; // 最后,垃圾收集器完成内存清理工作,销毁那些标记的值并回收他们所占用的内存空间; // 垃圾收集器是周期性运行的,这样会导致整个程序的性能问题; // 比如IE7以前的版本,他的垃圾收集器是根据内存分配量运行的,比如256个变量就开始运行垃圾收集器,这样就不得不频繁地运行,从而降低了性能; // 一般来说,确保占用最少的内存可以让页面获得更好的性能; // 最佳方案:一旦数据不再使用,将其值设置为null来释放引用,这个做法叫做解除引用; var o = { name:'lee'; }; o = null; // 解除对象引用,等待垃圾收集器回收;
三 小结