全局变量和局部变量 问题简单,修改太难,如果alert还能应付: result.push( new Function("alert('" +item+" "+list[i]+ "')") );如果是对象处理就有点勉强了^_^
fosjos(无聊的菜鸟程序员)
全局变量和局部变量 ----------------- handler都是分开的,应该没有全局和局部之分,还没有答到点上。但用new Function的确是对了,可以用它来处理这种情况。 ----------------- 那么看这个,明白了这个,上面的自然就应该明白了。:D<script type="text/javascript"> function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; }var sy = say667(); sy(); alert(sy.toString()); </script>
老问题了,原因有人说了,就是function被调用的时候变量不存在了, new Function是一种方法,但是不好,写法难看,而且还只能传递数字和字符串.---------------------------<script type="text/javascript"> function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + list[i]; result.push(function(i) {alert("item"+i)}.bind(list[i])); } return result; }Function.prototype.bind = function(){ var arg = arguments; var m = this; return function(){ m.apply(window,arg); } } function testList() { var fnlist = buildList([1,2,3]); for (var j = 0; j < fnlist.length; j++) { fnlist[j](); } }testList(); </script>
回来总结一下。有不对的地方,请指出来:D这道题是一个典型的闭包问题。似乎没有什么人对这个词感到"敏感"<script type="text/javascript"> function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + list[i]; //创建闭包。 result.push( function() {alert(item + ' ' + list[i])} ); } return result; }function testList() { var fnlist = buildList([1,2,3]); for (var j = 0; j < fnlist.length; j++) { fnlist[j](); } }testList(); </script>上面创建了闭包。闭包在buildList()退出后激活并使用。像C里面的话,这样调用,是会出错的,因为函数里的局部变量已经被消毁。而在js里,则是创建了闭包,他是一个函数退出后,留下的一个栈区(至少我是这么理解)。而其引用一直针对着list[i],注意,list[i]并非是从list中按值复制出来的参数。而是一直引用list[i],直到外函数退出,也就是buildList()退出时使用。(也就是说,在buildList()退出时,return result. i应该是3,因此得到的值为undefine。上面的例子一个套来套去的。因此下面这里可以很好的解释这个问题。<script type="text/javascript"> function say667() { // Local variable that ends up within closure var num = 666; var sayAlert = function() { alert(num); } num++; return sayAlert; }var sy = say667(); sy();//得到667,因function() { alert(num); }中的num并非是按值拷贝传递。而是一个引用。 </script>而解决方法是有很多种的。在一个函数中嵌套function,就是一个闭包...但是在一个函数中嵌套Function(注意,此Function第一个字符是大写)就是不一个闭包。所以Function是解闭包的一个方法,稻草人,也是一种方法,它把内嵌的function闭包,应用到最外层,通常应用此种方法来解决闭包的问题较好。比如也可以这样: <script type="text/javascript"> function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + list[i]; result.push(f(item)); } return result; }function f(i) { return function(){ alert(i); } } function testList() { var fnlist = buildList([1,2,3]); for (var j = 0; j < fnlist.length; j++) { fnlist[j](); } }testList(); </script>还要注意一点,就是闭包在与DOM用的时候,有可能会引用内存泄露...
<script type="text/javascript"> function buildList(list) { var result = []; for (var i = 0; i < list.length; i++) { var item = 'item' + list[i]; result.push( new Function('alert(\''+item + ' ' + list[i]+'\');')); } return result; }function testList() { var fnlist = buildList([1,2,3]); for (var j = 0; j < fnlist.length; j++) { fnlist[j](); } }testList(); </script>
sigh..
可憐的我
问题简单,修改太难,如果alert还能应付:
result.push( new Function("alert('" +item+" "+list[i]+ "')") );如果是对象处理就有点勉强了^_^
全局变量和局部变量
-----------------
handler都是分开的,应该没有全局和局部之分,还没有答到点上。但用new Function的确是对了,可以用它来处理这种情况。
-----------------
那么看这个,明白了这个,上面的自然就应该明白了。:D<script type="text/javascript">
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}var sy = say667();
sy();
alert(sy.toString());
</script>
<head>
<script>
var arrA = new Array();
function CheckObj(){
var anum = -1;
var inum = -1;
for(i=0;i<mybody.children.length;i++){
//alert (anum);
if(mybody.children(i).tagName=="A"){
anum = anum + 1;
arrA[anum] = 0 ;
mybody.children(i).attachEvent("onclick",function(){showdetail(anum)});
// alert( mybody.children(i).name + "\n" + "showdetail(" + anum +")");
}
if(mybody.children(i).tagName=="INPUT"){
inum = inum + 1;
arrA[inum] = 0 ;
mybody.children(i).attachEvent("onclick",function(){showdetail(inum)});
// alert( mybody.children(i).name + "\n" + "showdetail(" + inum +")");
}
}
function showdetail(objID) {
//alert(objID);
arrA[objID] = arrA[objID] + 1;
var nowtime = new Date();
alert("you have clicked the link " + "\n" + "\n"
+ " the link name is :" + event.srcElement.name + "\n"
+ " the link href is :" + event.srcElement.href + "\n"
+ " your have clicked this link " + arrA[objID] + " times \n"
+ " your clicked this link at " + nowtime + " \n"
);
/**/
for(i=0;i<arrA.length;i++){
div1.innerHTML += arrA[i] + "\n";
}
div1.innerHTML += "<br>";
}
}
</script>
<body id="mybody" onload="CheckObj()">
<a href="#" NAME="tagA" >aaaaa</a>
<a href="#" NAME="tagB" >bbbb</a>
<a href="#" NAME="tagC" >cccc</a>
<a href="#" NAME="tagD" >dddd</a>
<a href="#" NAME="tagE" >eeee</a>
<a href="#" NAME="tagF" >ffff</a>
<a href="#" NAME="tagG" >gggg</a>
<a href="#" NAME="tagH" >hhhh</a>
<a href="#" NAME="tagI" >iiiii</a>
<a href="#" NAME="tagJ" >jjjj</a>
<a href="#" NAME="tagK" >kkkkk</a>
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<INPUT TYPE="image" SRC="">
<div id="div1"></div>
</body></html>
所以testList中的循环用的是同一个值
此时i应该为3
而item为item3(最后一次的结果,即i为2的结果)
list[i]自然是undefined所以弹出3次item3 undefinedjs不太熟悉
瞎说的
:)
function()中引用的是function退出时的局部变量的值
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( new Function("show('"+item+"')"));
}
return result;
}
function show()
{
alert(arguments[0])
}function testList() {
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}testList();
</script>
result.push( function() {alert(item + ' ' + list[i])} );
这里item的只是个引用,所以是引循环最后一个值
而另一个i已经超出循环范围,所以是undefined
替代方法是 eval()方法构造一个字符串当成脚本执行
item是buildList函数中的局部变量;在闭包中有效;而list不是buildList中的局部变量;是无效的。
arrayObj必选项。一个 Array 对象。item, item2,. . . itemN可选项。该 Array 的新元素。说明
push 方法将以新元素出现的顺序添加这些元素。如果参数之一为数组,那么该数组将作为单个元素添加到数组中。如果要合并两个或多个数组中的元素,请使用 concat 方法。
一段小小的代碼,涉及到比較多的知識點:
1.push( )用法,如上所示,已講得很清楚。
2.function() 這里出現不是有點莫名其妙。有待高手解答
3.alert輸出怎麼會是“item3 undefined"後面多出了個undefined是哪個時候冒出來的
4.fnlist[j]()這個作用又是什麼呢
5.變量域的問題。上面雖然有同志提到,但我感覺跟這沒多大關系
6.變量值變化問題。這個需要考慮一下,三次輸出了”item3 undefined"
new Function是一种方法,但是不好,写法难看,而且还只能传递数字和字符串.---------------------------<script type="text/javascript">
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(function(i) {alert("item"+i)}.bind(list[i]));
}
return result;
}Function.prototype.bind = function(){
var arg = arguments;
var m = this;
return function(){
m.apply(window,arg);
}
}
function testList() {
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}testList();
</script>
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
//创建闭包。
result.push( function() {alert(item + ' ' + list[i])} );
}
return result;
}function testList() {
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}testList();
</script>上面创建了闭包。闭包在buildList()退出后激活并使用。像C里面的话,这样调用,是会出错的,因为函数里的局部变量已经被消毁。而在js里,则是创建了闭包,他是一个函数退出后,留下的一个栈区(至少我是这么理解)。而其引用一直针对着list[i],注意,list[i]并非是从list中按值复制出来的参数。而是一直引用list[i],直到外函数退出,也就是buildList()退出时使用。(也就是说,在buildList()退出时,return result. i应该是3,因此得到的值为undefine。上面的例子一个套来套去的。因此下面这里可以很好的解释这个问题。<script type="text/javascript">
function say667() {
// Local variable that ends up within closure
var num = 666;
var sayAlert = function() { alert(num); }
num++;
return sayAlert;
}var sy = say667();
sy();//得到667,因function() { alert(num); }中的num并非是按值拷贝传递。而是一个引用。
</script>而解决方法是有很多种的。在一个函数中嵌套function,就是一个闭包...但是在一个函数中嵌套Function(注意,此Function第一个字符是大写)就是不一个闭包。所以Function是解闭包的一个方法,稻草人,也是一种方法,它把内嵌的function闭包,应用到最外层,通常应用此种方法来解决闭包的问题较好。比如也可以这样:
<script type="text/javascript">
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push(f(item));
}
return result;
}function f(i) {
return function(){
alert(i);
}
}
function testList() {
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}testList();
</script>还要注意一点,就是闭包在与DOM用的时候,有可能会引用内存泄露...
function buildList(list) {
var result = [];
for (var i = 0; i < list.length; i++) {
var item = 'item' + list[i];
result.push( new Function('alert(\''+item + ' ' + list[i]+'\');'));
}
return result;
}function testList() {
var fnlist = buildList([1,2,3]);
for (var j = 0; j < fnlist.length; j++) {
fnlist[j]();
}
}testList();
</script>
国外的文章有所介绍,中文的比较少,这也是JS的一个特性,
在函数内部创建的function不会在函数结束时失效。
http://blog.morrisjohns.com/javascript_closures_for_dummies关于Closure和memory leaks:http://laurens.vd.oever.nl/weblog/items2005/closures/
http://siteexperts.spaces.live.com/Blog/cns!1pNcL8JwTfkkjv4gg6LkVCpw!338.entry
var item = 'item' + list[i];
result.push( function() {alert(item + ' ' + list[i])} );
这里item不越界,list[i]却越界呢?
http://community.csdn.net/Expert/topic/5048/5048563.xml看有没有怀念些什么^_^
你的blog吧?看到closure想起很多学校时候的事,怀念!
是啊,想当初,我还是刚学js,时间过得真的快:Dto:hb
是呀,呵呵,在学校的时光是最好的。不过也难得可以找到一起可以研究程序和一些底层的朋友呀:D