不用解释什么,你自己看看为什么!
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(e);
alert(events[e]);
};
} alert(obj.m1 == obj.m2);
obj.m1();
obj.m2(); </script>
</HEAD> <BODY>
</BODY>
</HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(e);
alert(events[e]);
};
} alert(obj.m1 == obj.m2);
obj.m1();
obj.m2(); </script>
</HEAD> <BODY>
</BODY>
</HTML>
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(events[e]); //请注意,这里events[e]的e变量的引用是global下的e就是全局变量,而不是保留的循环中的状态
};
}
//循环结束后全局变量e就是m2
alert(e);
/*
for (e in events) {
obj[e] = function (i) {
形参i,引用的是对传递过来的e引用的值的copy,所以它完成了保留当前执行的状态的要求即保留了当前的e值
return function () {
alert(events[i]); //这里引用了i
};
}(e); //执行一个函数
}
//返回的函数function(){alert...},引用了function (i)的执行环境,同时返回的function{alert...}又被全局变量引用,所以function (i)的执行环境不会释放,这种东西叫闭包。
//而在ff下可能做了一些优化,就是说会检测返回的function(){alert...}里是否有对上函数外部的引用,如果没有引用则释放执行环境,当然,这样会产生一些BUG。。这个例子里返回的function(){alert...}有对外部的引用i是函数里没有的所以,FF不会优化它
*/
alert(obj.m1 === obj.m2); //成员引用的函数不同,可是函数里引用的e变量相同,而===则是比较的m1和m2函数的引用,而不是比较函数里的那个e的引用。。
obj.m1(); //结果可想而知
obj.m2(); </script>
</HEAD> <BODY>
</BODY>
</HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(events[e]);
return e;
};
} alert(obj.m1 === obj.m2);
alert(obj.m1() === obj.m2()); </script>
</HEAD> <BODY>
</BODY>
</HTML>
[code=JScript]<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
/*
//请注意,这里events[e]的e变量的引用是global下的e就是全局变量,而不是保留的循环中的状态 你的意思是events[e]中的e是window下的e,不是var events = {m1 : "clicked",m2: "changed"};
中的属性? 为什么啊?
那for循环循环一次 不应该将它语块中的function实例化么?然后赋值给obj[e]?? 你说的是正确的,但我就是理解不过来,你能不能把闭包给我细讲下。。 我再追加100分 */
for(e in events){
obj[e] = function(){
alert(events[e]); }; }
</script>
</HEAD> <BODY>
</BODY>
</HTML>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
/*
//请注意,这里events[e]的e变量的引用是global下的e就是全局变量,而不是保留的循环中的状态 你的意思是events[e]中的e是window下的e,不是var events = {m1 : "clicked",m2: "changed"};
中的属性? 为什么啊?
那for循环循环一次 不应该将它语块中的function实例化么?然后赋值给obj[e]?? 你说的是正确的,但我就是理解不过来,你能不能把闭包给我细讲下。。 我再追加100分 */
for(e in events){
obj[e] = function(){
alert(events[e]); }; }
</script>
</HEAD> <BODY>
</BODY>
</HTML>
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
if(e=="m1"){
obj.m1 = function(){
alert(events.m1);
};
}
else{
obj.m2 = function(){
alert(events.m2);
};
}
}
alert(obj.m1 == obj.m2);
obj.m1();
obj.m2() </script>
</HEAD> <BODY>
</BODY>
</HTML>
你看这个你就明白了
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"};for(e in events){
alert(e);
obj[e] = function(){
alert(e); //m2
alert(e === window.e); //true
//alert(events[e]);
};
}
alert(e); //m2
obj.m1();
/*
你的意思是events[e]中的e是window下的e,不是var events = {m1 : "clicked",m2: "changed"};
中的属性?你测试看下。。
就知道了
循环结束后
e的引用值是m2
而那个function里引用的e正是全局变量e
因为function里没有变量e,所以它会根据作用域链去上层找e
它的上层只有window,所以它找到的就是window.e
*/
</script>
obj[e] = function(){
alert(events[e]); }; } 这个实际最终得到的是obj.m1 = function(){
alert(events.m2);
};
obj.m2 = function(){
alert(events.m2);
};
这里的e是属于events对象的么?
这里的 for(e in events)
这个是属于events对象的
alert(e);
obj[e] = function(){
alert(events[e]);
};
}
就可以得到他的值
你说的很好,但我现在就这还是迷糊 请指教下。。
<script type="text/javascript">
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(events[e]);
};
}
/*
就这块我还是有点迷糊
你说这个for in语句不可以分解为这两个过程么?
第一次循环: obj[m1] = function(){alert(events[m1])}; 第二次循环: obj[m2] = function(){alert(events[m2])};
*/</script>
并不是e在作怪
我再加输出给你看<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
if(e=="m1"){
obj.m1 = function(){
alert(e)//看看这里最终输出的是m1还是m2
alert(events.m1);
};
}
else{
obj.m2 = function(){
alert(e)
alert(events.m2);
};
}
}
alert(obj.m1 == obj.m2);
obj.m1();
obj.m2() </script>
</HEAD> <BODY>
</BODY>
</HTML>你自己看看
对呀 按你这说法 我就迷糊了 既然e是events中的对象,那为什么两次就只得到了m2的值?
obj[m1] = function(){alert(events.m2)};
obj[m2] = function(){alert(events[e])};
for(e in events){
obj[e] = function(){
alert(events[e]); }; }
})();改成这样也是同样的结果我的理解是两个function中引用的是同一个e
而e的最终值是m2我上面5楼的测试应该已经证实了至于e是全局变量,其实是楼主编程上的一个错误
e和events对象没有关系.
它只不过是用来放events成员的名字.
而function里的操作是通过e得到成员的名字,然后在通过events对象来找到成员的值
所以e变了..
函数读的值自然也就变了.如这个for in语句应分解为
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(events[e]);
}();//让函数提前执行就可以了
} alert(obj.m1 === obj.m2);
obj.m1();
obj.m2(); </script>
</HEAD> <BODY>
</BODY>
</HTML>chinmo 刚才考虑了下,也许确实是循环作的怪,你说匿名函数
function(){
alert(events[e]);
}
/*
你说它在循环时候并没有赋值对不?
*/
第一次如果不操作obj.m1那么obj.m1= function(){alert(events[e])};
那么在你使用obj.m1()得值就不会是m2得
语句执行到下面的时候已经没有了循环只有
第一种情况
obj.m1= function(){alert(events[e])};//按你说的第二次没有操作得到的
obj.m2= function(){alert(events.m2)};而我认为得obj.m1= function(){alert(events.m2)};//按你说的第二次操作了obj.m1
obj.m2= function(){alert(events.m2)};
obj.m1= function(){alert(events[e])};//按muxrwc 说的第二次没有操作得到的
obj.m2= function(){alert(events.m2)}; 而我认为得 obj.m1= function(){alert(events.m2)};//按我说的第二次操作了obj.m1
obj.m2= function(){alert(events.m2)};
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<script>
var obj = new Object();
var events = {m1 : "clicked",m2: "changed"}; for(e in events){
obj[e] = function(){
alert(events[e]);
};
alert(obj[e])//这里你看看,你就清楚了
} alert(obj.m1 === obj.m2);
obj.m1();
obj.m2(); </script>
</HEAD> <BODY>
</BODY>
</HTML>
第二次怎么可能操作obj['m1']...obj.m1= function(){alert(events[e])};
obj.m1= function(){alert(events.m2)};
这俩完全两个概念...
虽然变量查找方式是一样的.
但是第一个是通过作用域链来找到的events然后在找到e
然后去获得的events[e]的值
而第二个是通过作用域链来找到的events并获得它的m2值我的意思是,m1和m2的设置每个只发生一次...而m1和m2引用的函数执行的时候,通过scope chain来找的e,因为循环执行结束后
e的引用值是m2(在我最初的回复里有alert(e),就是为了说明这点)
所以它们都打印出了event[m2]的值,也可以把它们理解成
obj.m1= function(){alert(events.m2)};
但是实际上的执行流程,是我在4楼和9楼所说的那样...
obj[e] = function(){
alert(events[e]);
};
这里产生了一个闭包.
alert(events[e]); 这句话中间的e开始依赖于外层的变量e.所以会一直是第2个.
关于闭包的概念有点复杂,楼主可以去找找资料.