找回密码
 注册

QQ登录

只需一步,快速开始

查看: 2428|回复: 21

new Function的疑问

[复制链接]
发表于 2009-3-20 21:18:46 | 显示全部楼层 |阅读模式
<script language="javascript" type="text/javascript">
function test(){
        for (var i=1; i<4; i++){
                document.getElementById("b"+i).attachEvent("onclick",new Function('alert("This is button'+i + '");'));
        }
}
</script>
哪位高人帮我解释一下,为什么new Function('alert("This is button'+i + '");这里这个i会被正确传递?
发表于 2009-3-20 22:16:52 | 显示全部楼层
上面那个循环,效果是这样的:
document.getElementById("b1").attachEvent("onclick",new Function('alert("This is button1");'));
document.getElementById("b2").attachEvent("onclick",new Function('alert("This is button2");'));
document.getElementById("b3").attachEvent("onclick",new Function('alert("This is button3");'));
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-20 22:28:44 | 显示全部楼层
谢谢你的回答,但我还想问一下,为什么这个时候i的值就得到了哪?
document.getElementById("b"+i).onclick=function(){alert(i)};这样是得不到的
new Function("alert("+i+")");应该可以理解成这样吧function(){alert(i)}
但为什么结果却不一样哪?new Function("alert("+i+")")却可以得到i的当前值,而不是等for执行完以后才获得i值的
回复 支持 反对

使用道具 举报

发表于 2009-3-20 22:31:46 | 显示全部楼层
如果你稍微仔细一点你可以在你的帖子下面不远的地方有个标题是:“  我对javascript中闭包(closure)的理解 ”
的帖子
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-20 22:35:39 | 显示全部楼层
楼上误解我的意思了,我知道通过闭包可以保留对i值的引用,但我问的是new Function()的问题,它也可以获得i值,但看上去它并不像一个闭包(我个人认为),我想知道它是通过什么原理获得i值的
回复 支持 反对

使用道具 举报

发表于 2009-3-20 22:39:52 | 显示全部楼层
原帖由 [i]yqhehe 于 2009-3-20 22:35 发表
楼上误解我的意思了,我知道通过闭包可以保留对i值的引用,但我问的是new Function()的问题,它也可以获得i值,但看上去它并不像一个闭包(我个人认为),我想知道它是通过什么原理获得i值的
原帖由 [i]yqhehe 于 2009-3-20 22:35 发表
楼上误解我的意思了,我知道通过闭包可以保留对i值的引用,但我问的是new Function()的问题,它也可以获得i值,但看上去它并不像一个闭包(我个人认为),我想知道它是通过什么原理获得i值的

闭包是不是运行一个function然后在function内部保留要用到的值?
new Function是不是产生一个新的function?这个function是动态生成的,变量,参数也是动态生成的,是不是保留了要用到的值?

我看不是我误解你的意思
是你自己都不知道自己什么意思

[[i] 本帖最后由 pigu 于 2009-3-20 22:41 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-3-20 22:54:01 | 显示全部楼层
楼上的火气那么大干吗?我要是知道,也不会到这来请教的,我就是不感确定new Function()是以什么方式保存i值,也不明白它怎样实现的闭包。。。。。。不过还是要感谢你的回答,现在明白了
回复 支持 反对

使用道具 举报

发表于 2009-6-11 09:09:21 | 显示全部楼层
我看你还是没明白.
sth.onclick=(function(m){return function(){alert(m)}})(i)  这个你明白不? 如果这个明白了,你就明白了.
回复 支持 反对

使用道具 举报

发表于 2009-6-11 09:46:58 | 显示全部楼层
new Function没有闭包
就是一字符串
就是给字符串赋值
回复 支持 反对

使用道具 举报

发表于 2009-6-11 12:26:33 | 显示全部楼层
跟闭包无关,new Function,就是新定义了一个function,i的值也作为这个新的function的参数固化在其内部了。

那句话的本质同8楼。

[[i] 本帖最后由 jubdit 于 2009-6-11 12:37 编辑 ]
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-11 15:06:11 | 显示全部楼层
原帖由 [i]forbe 于 2009-6-11 09:09 发表
我看你还是没明白.
sth.onclick=(function(m){return function(){alert(m)}})(i)  这个你明白不? 如果这个明白了,你就明白了.

......这个都被你翻出来了,这个问题我的确早就知道了,虽然我说话有点直接,但是不至于招致你如此的“关注"吧,你描述的这个虽然是个闭包,但用来描述new Function形成过程过于牵强,pigu的说法才更为合理,不过还是感谢你对我以前问题的解答
回复 支持 反对

使用道具 举报

发表于 2009-6-12 09:22:11 | 显示全部楼层
哈哈.一笑而过. 进取的程序员是好的.
回复 支持 反对

使用道具 举报

发表于 2009-6-12 11:31:01 | 显示全部楼层
看这个attachEvent 这是ie特有的事件监听方法
attachEvent(evType,fn);
这个方法要求 第一个参数是事件类型 第2个必须是函数 function都是Funtion实例化而来的 用new Funtion 等于实例化了一个Funtion;
document.getElementById("b"+i).attachEvent("onclick",new Function('alert("This is button'+i + '");'));

等价于
document.getElementById("b"+i).attachEvent("onclick",function('alert("This is button'+i + '");'));

如果你要使用这种方式
document.getElementById("b"+i).onclick=function(){alert(i)};

可以试试这个
document.getElementById("b"+i).onclick=function(i){alert(i)}();

未置可否 见笑见笑
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:25:16 | 显示全部楼层
原帖由 [i]yqhehe 于 2009-3-20 22:28 发表
谢谢你的回答,但我还想问一下,为什么这个时候i的值就得到了哪?
document.getElementById("b"+i).onclick=function(){alert(i)};这样是得不到的
new Function("alert("+i+")");应该可以理解成这样吧function(){a ...


本来不想说了,因为感觉楼主没有真正思考为什么别人会这么回复,别人给的答案可能只是一个引子或者提示,是希望你自己去思考的。

解释:
Function,你可以把它当作一个你在前面已经定义的function,像这样:
var Function = function(param){……};

你在new Function(……)的时候,括号中的内容实际是当作参数传递的,如果这个参数是表达式,会先计算结果,最后只是把运算结果的值传递过去。

在你的例子中,i=0的时候传递的就是“alert(0)”,也就是说在你绑定事件的时候new Function这个过程就已经将"i"固化到字符串参数里了,并不是后来事件触发的时候可以读去到“i”。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:34:01 | 显示全部楼层
2212真的很诚实,说见笑就让人笑。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:36:19 | 显示全部楼层
最后罗嗦一句:

new Function("alert("+i+")"); 一定要等效于非new方式的写法的话,

只能近似等效于:function(param){return someNativeOperation(param);};(这里return的是一个function,就是Fuction后面括号中的内容转换而来的。)

绝对不等效于你说的:function(){alert(i)};

其实8楼的兄弟已经提示地很清楚了,你都把他冤死了。。。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:37:51 | 显示全部楼层
呵呵。难道你没习惯?
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:39:49 | 显示全部楼层
混BI的话这种情况比较多。小生经常碰到某奇葩然后被他喷呢。 楼上的楼上应该养成这样的习惯。见怪不怪。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:40:48 | 显示全部楼层
原帖由 [i]forbe 于 2009-6-13 12:37 发表
呵呵。难道你没习惯?


在BI是不是老鸟都要被菜鸟欺负的?谨以菜鸟之身向老鸟们致敬。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 12:42:41 | 显示全部楼层
原帖由 [i]forbe 于 2009-6-13 12:39 发表
混BI的话这种情况比较多。小生经常碰到某奇葩然后被他喷呢。 楼上的楼上应该养成这样的习惯。见怪不怪。


看来在BI好人不易做啊。
回复 支持 反对

使用道具 举报

发表于 2009-6-13 13:17:43 | 显示全部楼层
new Function , eval, 闭包 貌似都不会被回收吧! 我当初也问过这个问题
回复 支持 反对

使用道具 举报

发表于 2009-6-13 14:24:16 | 显示全部楼层
呵呵。大概是比较难做。哈哈。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )

GMT+8, 2021-4-14 19:17 , Processed in 0.066452 second(s), 9 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表