各路大侠来看看,这个是闭包还是什么原理?

yxixhdfqwe 2012-04-25 10:35:39
<script type="text/javascript">
var testOne;
function Test1() {
this.a = 1;
}
function Test2(t) {
t.a = 2;
t = null;
t = {};

testOne = null;
alert(t.a);//undefined
}

function Main() {
testOne = new Test1();
var testTwo = new Test1();

//testOne = null;//在这里直接赋为空,对象也被消灭了
//testTwo = null;//在这里直接赋为空,对象也被消灭了

Test2(testOne);
Test2(testTwo);
if (testOne) {//全局变量,对象已经为空 不满足条件
alert(testOne.a);
}
alert(testTwo.a);//仍然显示 2

}
</script>

我想问的是,
第一:Test2函数 里的参数传入的到底是值还是引用,
如果是值,为什么改变了属性值,函数外使用也改变了.
如果是引用,为什么函数里都是赋为空了,外面仍然能访问.

第二:如果是全局变量,无论在函数里还是外赋值为空,就彻底被消灭了.
如果不是传值来赋为空,在申明的作用域里赋为空,也会被消灭.

描述可能有点混乱,但是大牛应该能懂我的意思,现在仅仅能知道结果,不知道原理,十分不爽,求解释下原理.十分感谢!
...全文
163 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
豪情 2012-04-26
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 的回复:]

其实闭包就是将函数返回,并且连同他的活动变量一起,就这么简单啊。
http://blog.csdn.net/a569171010/article/details/7484461
希望对你有帮助。
[/Quote]
这个文章写真不错,浅显易懂啊。
峭沙 2012-04-26
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

2楼你解释的只是结果,但是为什么是这样的,求原理啊!
[/Quote]这是常识,任何编程语言都是这样。常识你让人怎么跟你讲原理。。
给你个建议吧,google javascript 引用变量
荔枝 2012-04-26
  • 打赏
  • 举报
回复
其实闭包就是将函数返回,并且连同他的活动变量一起,就这么简单啊。
http://blog.csdn.net/a569171010/article/details/7484461
希望对你有帮助。
未知数 2012-04-26
  • 打赏
  • 举报
回复
首先,你认为的给变量赋值为null就消灭了对象,这个理解是错误的,给变量赋值只是改变变量指向的内存,对象并没有被消灭
例如:
var obj1={a:1};
var obj2=obj1;//obj2=obj1,两个变量表示同一个对象
obj1=null;//给obj1赋值为空,只是改变了obj1的指向,消灭对象了么?
alert(obj2.a);//弹出1,说明对象没有被消灭

给你解释test2函数
function Test2(t) {
t.a = 2;//传入的对象a属性赋值为2
t = null;//给t重新赋值,现在t不再指向传入的对象,但对象并没有被消灭,这个一定要清楚,也就是说传入的对象a属性已经被赋值,并且后面的对t的操作不再影响传入的对象。
t = {};//t已经和传入的对象无关了,这句只能是打酱油

testOne = null;//这句话才有用,直接把变量testOne赋值为null
alert(t.a);//t已经和传入的对象无关了,这儿出现什么和t初始传入的对象毛的关系都没得
}

关键是理解,不要混淆概念,以为给变量重新赋值就是给对象重新赋值,变量只是保存一个地址,不是对象本身
峭沙 2012-04-26
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

写错个地方,(可以理解为把指路牌摘除了,所以你就找不到路了)
应该是(可以理解为把指路牌摘除了,但是你要去的地方还是存在的)
[/Quote]恭喜你开窍了,呵呵,你的比喻很恰当的说
yxixhdfqwe 2012-04-26
  • 打赏
  • 举报
回复
写错个地方,(可以理解为把指路牌摘除了,所以你就找不到路了)
应该是(可以理解为把指路牌摘除了,但是你要去的地方还是存在的)
yxixhdfqwe 2012-04-26
  • 打赏
  • 举报
回复

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AjaxTest
{
public partial class 变量引用测试 : System.Web.UI.Page
{
public void destory(ref Test t)
{
t.a = 2;
t = null;
}
public void destory(Test t)
{
t.a = 2;
t = null;
}
protected void Page_Load(object sender, EventArgs e)
{
Test test1 = new Test();
Test test2 = new Test();


destory(test1);
destory(ref test2);

this.div1.InnerText = test1.a.ToString();//显示2
if (test2!=null)//test2=null
{
this.div2.InnerText = test1.a.ToString();
}

}
}
public class Test
{
public int a = 1;
}
}

首先非常感谢2楼得回帖,于是我用C#试了试,想了想,大概意思终于弄明白了
C#里面,不加ref 关键字
test1变量指向的地址是对象的地址,所以修改变量后,值发生了改变(可以变态点理解为,修改了
指路牌指向的地址,你要去的地方也变得和指路牌一样了),但是复制为null,等于说是把变量
复制 为null,(可以理解为把指路牌摘除了,所以你就找不到路了)
加了ref 关键字 test2变量就等同于当前的地址(可以理解为变量就是地址,所以改变变量也就改变了地址,销毁了变量也就销毁了地址)
yxixhdfqwe 2012-04-25
  • 打赏
  • 举报
回复
如果我现在需求就是要在函数里设置为空,除了把对象设为全局变量,就没有其他办法了么?
峭沙 2012-04-25
  • 打赏
  • 举报
回复
		var obj = {
name: "test"
}
function test1(o){
o.name = "test1";
}
function test2(o){
o.name = "test2";
o = null;
}

alert(obj.name); // test
test1(obj);
alert(obj.name); // test1
test2(obj);
alert(obj.name); // test2
obj = null;
alert(obj.name); // exception: obj is null
峭沙 2012-04-25
  • 打赏
  • 举报
回复
参数为对象时是引用传递,你在里面对其属性的修改都要体现在外面的对象上,而在函数里面将其置为空,只是将参数置为空,原来的对象纹丝未动
yxixhdfqwe 2012-04-25
  • 打赏
  • 举报
回复
恳请大牛指点迷津,在线坐等!
yxixhdfqwe 2012-04-25
  • 打赏
  • 举报
回复
2楼你解释的只是结果,但是为什么是这样的,求原理啊!

87,920

社区成员

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

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