关于javascript对象的一个问题( 关于变量的生存周期 )

zxcullx 2013-09-01 04:43:32
假设有如下javaScript代码:

//Point A:

function f(arg){
this.property = arg;
}

var a = new f(1);

//Point B:

我想知道的是:当程序运行到Point B的时候, a对象中的变量arg是否还存在,或是已被销毁?

( 请真正了解原理的朋友回答,如果你对自己的答案不是很有把握,请不要回答 )

...全文
325 22 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
22 条回复
切换为时间正序
请发表友善的回复…
发表回复
zxcullx 2013-09-06
  • 打赏
  • 举报
回复
fzfei2的代码可以用了,我做了一番测试,只是粗略的测试,所以结论不敢说是准确的,以下观点仅供参考: 构造函数的局部变量能否得到保留,完全取决于是否创建了一个闭包。如果创建的是闭包,所有的变量都将得到保留,否则全部将被丢弃。但在决定何时创建一个闭包这一点上,不同的浏览器有不同的策略。 不能说问题已经完全解决了,但至少可以告一段落了。在此感谢fzfei2提供了关键的分析工具以及很好的建议,同时也感谢其他朋友的热情参与。
fzfei2 2013-09-05
  • 打赏
  • 举报
回复
引用 20 楼 zxcullx 的回复:
[quote=引用 16 楼 fzfei2 的回复:] 为了直观体验,利用VBS对象析构的功能,来提示是否释放,只能在IE 下测试 你可以修改 f 里的代码进行测试

<title>测试GC</title> 
<script language="vbs">
Class C
		public property get value
		value="ok"
		end property
	 
   Private Sub Class_Terminate   
      MsgBox("释放了")
   End Sub
End Class
function vbObj()
	set vbObj= new C
end function 
</script>
<button onclick="test()">创建对象</button>
<button onclick="javascript:a=null">主动释放</button>
<script>
var a;
function f(arg){
	  this.xx=function(){ alert( arg.value ) }  //如果这里有引用 不会马上会释放
	 // this.yy=function(){ alert( eval('1+2')  ) }  //有eval 的也不会马上释放
	 //this.zz=function(){}   //会马上释放
}	
function test(){
	var o=vbObj();
	 a=new f(o);
}
setInterval(CollectGarbage, 500);
</script>
在ie下测试显示网页有错误:test() 类型不匹配。 我想知道,你表达的是不是这么一个意思: 在构造函数中的局部变量,被成员引用到的将会被保留,而没有引用的则会被丢弃。 [/quote] 应该是说外部有引用到肯定会保留, 我实验用eval() 是表达式,表达式中没有用到,但也没有释放,所以说是可能被引用到了,也不会释放。 我原来在IE10下,现改了下应该兼容低版本的了,你做一下实验就知道了

<title>测试GC</title> 
<script language="vbs">
Class C
		public property get value
		value="ok"
		end property
	 
   Private Sub Class_Terminate   
      MsgBox("释放了")
   End Sub
End Class
function vbObj()
	set vbObj= new C
end function 
</script>
<button onclick="javascript:test()">创建对象</button>
<button onclick="javascript:a=null">主动释放</button>
<script language="javascript">
var a;
function f(arg){
	  this.xx=function(){ alert( arg.value ) }  //如果这里有引用 不会马上会释放
	 // this.yy=function(){ alert( eval('1+2')  ) }  //有eval 的也不会马上释放
	 //this.zz=function(){}   //会马上释放
}	
function test(){
	var o=vbObj();
	 a=new f(o);
}
setInterval(CollectGarbage, 500);
</script>
zxcullx 2013-09-05
  • 打赏
  • 举报
回复
引用 16 楼 fzfei2 的回复:
为了直观体验,利用VBS对象析构的功能,来提示是否释放,只能在IE 下测试 你可以修改 f 里的代码进行测试

<title>测试GC</title> 
<script language="vbs">
Class C
		public property get value
		value="ok"
		end property
	 
   Private Sub Class_Terminate   
      MsgBox("释放了")
   End Sub
End Class
function vbObj()
	set vbObj= new C
end function 
</script>
<button onclick="test()">创建对象</button>
<button onclick="javascript:a=null">主动释放</button>
<script>
var a;
function f(arg){
	  this.xx=function(){ alert( arg.value ) }  //如果这里有引用 不会马上会释放
	 // this.yy=function(){ alert( eval('1+2')  ) }  //有eval 的也不会马上释放
	 //this.zz=function(){}   //会马上释放
}	
function test(){
	var o=vbObj();
	 a=new f(o);
}
setInterval(CollectGarbage, 500);
</script>
在ie下测试显示网页有错误:test() 类型不匹配。 我想知道,你表达的是不是这么一个意思: 在构造函数中的局部变量,被成员引用到的将会被保留,而没有引用的则会被丢弃。
大悟飞天 2013-09-04
  • 打赏
  • 举报
回复
楼主,我就不写一堆了,简而告之吧: 在这种情况下,arg依旧存在,原因在于a对象的property属性依然保持着对arg的引用,这种情况下,arg不会被GC回收,也就不会被释放掉了。你可以亲自用调试器测试就知道。 望采纳!
zhjdg 2013-09-04
  • 打赏
  • 举报
回复
在你那例子中 arg 是临时变量 永远都是瞬间存在
zxcullx 2013-09-04
  • 打赏
  • 举报
回复
说说我对于各位见解的理解吧: //Point A: function f(arg1, arg2){ arg1 = arg2; this.property = function{ return arg1; } } var x = {x:'a'}, y = {y:1}; var a = new f(x, y); //Point B: 结论:当程序执行到Point B时, arg1的值为{y:1},而arg2的值为undefined。 这个结论正确吗?
fzfei2 2013-09-03
  • 打赏
  • 举报
回复
为了直观体验,利用VBS对象析构的功能,来提示是否释放,只能在IE 下测试 你可以修改 f 里的代码进行测试

<title>测试GC</title> 
<script language="vbs">
Class C
		public property get value
		value="ok"
		end property
	 
   Private Sub Class_Terminate   
      MsgBox("释放了")
   End Sub
End Class
function vbObj()
	set vbObj= new C
end function 
</script>
<button onclick="test()">创建对象</button>
<button onclick="javascript:a=null">主动释放</button>
<script>
var a;
function f(arg){
	  this.xx=function(){ alert( arg.value ) }  //如果这里有引用 不会马上会释放
	 // this.yy=function(){ alert( eval('1+2')  ) }  //有eval 的也不会马上释放
	 //this.zz=function(){}   //会马上释放
}	
function test(){
	var o=vbObj();
	 a=new f(o);
}
setInterval(CollectGarbage, 500);
</script>
KK3K2005 2013-09-03
  • 打赏
  • 举报
回复
引用 11 楼 zxcullx 的回复:
[quote=引用 9 楼 KK3K2005 的回复:] 你要这样考虑 var a = b; 假如 b 是常量 那么肯定销毁了 没有存在的意义 如果b是一个对象的引用 那么 这个对象还在 但是 b没了
“销毁一个常量”,你确定这句话没有语法问题? 如果b是一个对象的引用,那么现在a和b都指向同一个对象了,并且由于a是一个局部变量,所以b的存活时间至少不会少于a。 如果b不再有后续的访问,如果有必要的话,编译器毫无疑问会覆盖其所在的寄存器,但这并不表示b就不存在了,这只是一种代码优化技术。 我把问题改一下吧: //Point A: function f(arg){ this.property = function{ return arg; } } var a = new f(1); //Point B: 当然,在这种情况下,arg必然存在。请告诉我,这个对象,和楼顶所说的对象,有何不同?编译器如何区分这两种情形? 这个问题可能比较难,但我想得到正确的答案而不是众说纷纭,如果没人知道,我也能够理解。 ( 请真正了解原理的朋友回答,如果你对自己的答案不是很有把握,请不要回答 ) [/quote] 不要咬文嚼字
天际的海浪 2013-09-03
  • 打赏
  • 举报
回复
看看这个吧,希望你能看懂 http://www.nowamagic.net/librarys/veda/detail/1305
fzfei2 2013-09-03
  • 打赏
  • 举报
回复
如果 arg 不是对象是常量,向外部方法没有引用,是会是消的
zxcullx 2013-09-03
  • 打赏
  • 举报
回复
引用 9 楼 KK3K2005 的回复:
你要这样考虑 var a = b; 假如 b 是常量 那么肯定销毁了 没有存在的意义 如果b是一个对象的引用 那么 这个对象还在 但是 b没了
“销毁一个常量”,你确定这句话没有语法问题? 如果b是一个对象的引用,那么现在a和b都指向同一个对象了,并且由于a是一个局部变量,所以b的存活时间至少不会少于a。 如果b不再有后续的访问,如果有必要的话,编译器毫无疑问会覆盖其所在的寄存器,但这并不表示b就不存在了,这只是一种代码优化技术。 我把问题改一下吧: //Point A: function f(arg){ this.property = function{ return arg; } } var a = new f(1); //Point B: 当然,在这种情况下,arg必然存在。请告诉我,这个对象,和楼顶所说的对象,有何不同?编译器如何区分这两种情形? 这个问题可能比较难,但我想得到正确的答案而不是众说纷纭,如果没人知道,我也能够理解。 ( 请真正了解原理的朋友回答,如果你对自己的答案不是很有把握,请不要回答 )
KK3K2005 2013-09-03
  • 打赏
  • 举报
回复
为什么b 没了 因为 后续代码 对b没有一个预期的访问
KK3K2005 2013-09-03
  • 打赏
  • 举报
回复
你要这样考虑 var a = b; 假如 b 是常量 那么肯定销毁了 没有存在的意义 如果b是一个对象的引用 那么 这个对象还在 但是 b没了
zxcullx 2013-09-02
  • 打赏
  • 举报
回复
我觉得按道理来说,这个变量应该被销毁。否则的话,将会造成内存的巨大浪费。 但我对javaSript的了解还不够深入,所以才发贴一问。 但各位的回答都缺乏说服力,基本上自己怎么认为就怎么说。我不知道该相信哪一个。 ( 请真正了解原理的朋友回答,如果你对自己的答案不是很有把握,请不要回答 )
tcmakebest 2013-09-01
  • 打赏
  • 举报
回复
arg 只是形参,他只是代理别人完成一件事,所以这个问题其实是没有意义的。 请看下面的代码:楼主其实应该在这个地方关心变量 i,而不是 arg。 var i = 1; var a = new f(i);
阿鱼 2013-09-01
  • 打赏
  • 举报
回复
同意5楼的回答。 a作为一个实例化对象是不存在变量arg的,变量arg是在构造函数执行的时候(new f(1))即实例化的时候存在,执行完毕后便已经被销毁。
天际的海浪 2013-09-01
  • 打赏
  • 举报
回复
a对象中没有arg, arg只是构造函数中的临时变量 运行到Point B的时候,临时变量arg不存在了,已被销毁 但a对象中property属性会存在的
天际的海浪 2013-09-01
  • 打赏
  • 举报
回复
a对象中没有arg, arg 运行到Point B的时候, a对象中的变量arg是否还存在,或是已被销毁? arg this.property
fzfei2 2013-09-01
  • 打赏
  • 举报
回复
会存在的 ....
似梦飞花 2013-09-01
  • 打赏
  • 举报
回复
你调下试试呗
加载更多回复(1)

87,997

社区成员

发帖
与我相关
我的任务
社区描述
Web 开发 JavaScript
社区管理员
  • JavaScript
  • 无·法
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧