关于JavaScript中的堆变量

      父作用域中的局部变量会污染到子作用域,当然,可以在子作用域中可以重新声明这个变量来覆盖父作用域的污染。但是即便如此结果依然与干净的作用域不同。重定义变量后变量依然存在,只是值为undefined。干净的作用域中访问不存在的变量应该会抛出异常。
(function(){
  var n="次碳酸钴";
  (function(){
    var n;
    alert(n); //undefined
  })();
})();
(function(){
  var n="次碳酸钴";
  delete n;
  (function(){
    alert(n); //次碳酸钴
  })();
})();
(function(){
  (function(){
    alert(n); //Error: n is not defined 
  })();
})();
  

     现在我们知道,要保持子作用域是干净的就不能在父作用域中使用局部变量。现在有这样一个需求,父作用域中有两个子作用域,第一个子作用域运行后会返回一个对象,第二个子作用域是干净的。然后需要把第一个子作用域返回对象的各个键作为第二个作用域的局部变量(键的个数和值是不固定的),也就是在一个干净的作用域中导入一组变量。类似下面这个with语句所完成的效果,但是with语句对效率影响巨大,不能使用它。必须找到一种方法来模拟这个with。
(function(){
  with(function(){
    return {a:"1",b:"2",c:"3"};
  }())(function(){
    alert(a+b+c); //123
  })();
})();
  

      如果不能在父作用域使用局部变量就有点麻烦了。其实,通常变量的指针是储存在栈中的,var和function语句会预执行就是因为需要计算作用域中局部变量指针所占空间的大小,从而给他们分配内存。栈中的东西是不能随意删除的,所以我们无法删除这些变量。但是某些情况下变量也可以放在堆中,比如使用eval执行var语句在运行过程中动态定义变量。由于栈空间的计算在作用域运行前就计算好的,运行过程中动态定义的变量就无法插入栈中,所以被临时分配到了堆中。既然是在堆中,我们就可以随意的删除它,这样就不会污染到其它作用域了。
(function(){
  eval("var i,o");
  o=function(){
    return {a:"1",b:"2",c:"3"};
  }();
  for(i in o)eval("var "+i+"=o[i]");
  delete i,delete o;
  (function(){
    alert(a+b+c); //123
    alert(i); //Error: i is not defined 
  })();
})();
  

     其实,对于这个需求有更好的解决办法,这篇只是说堆变量的就不扯过去了。下一篇中咱使用其它办法来解决这个问题。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值