javascript – 如何使此代码工作?
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 如何使此代码工作?,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4911字,纯文字阅读大概需要8分钟。
内容图文
![javascript – 如何使此代码工作?](/upload/InfoBanner/zyjiaocheng/715/efd2e89c02a845138862ad0026bfb75a.jpg)
参见英文答案 > JavaScript closure inside loops – simple practical example 43个
代码给了我:
一个
乙
C
当我点击A B C时,它总是向我显示最后一个“伏特加”.
我想要“马丁”(A),“林赛”(B),“伏特加”(C)
请帮我解释一下我的例子.
myArray = [
{
letter: "A",
brand: "martin"
},
{
letter: "B",
brand: "lindsay"
},
{
letter: "C",
brand: "vodka"
}
];
var list = '';
for (var i = 0; i < myArray.length; i++) {
list += "<br>" + myArray[i].letter;
new_info = myArray[i].link;
(function(new_info) {
$(this).click(function(){ //this - refers to A or B or C
$('#box2').text(new_info);
});
}).call(this, myArray[i])
}
$('#box1').append(list);
解决方法:
编辑:
我说我不会为你编写代码……好吧,我做了:this fiddle完全符合您的要求.我用上下文(this),闭包问题和隐含的全局变量解决了这个问题.它仍然需要大量工作,但小提琴显示了每个人都在说的内容:$(this)不会,不能也不会指向像“A”或“B”这样的字符串常量.
很抱歉这样说,但是你的代码充满了问题,但我会在这里解决你要问的具体问题.
在循环内部,您将分配一个单击处理程序,基本上如下所示:
function()
{
$('#box2').text(new_info);
}
其中new_info是在更高范围内声明的变量.到现在为止还挺好.问题是,您正在创建的函数对象没有自己的副本,无论该变量(new_info)在创建该函数时碰巧保留了什么值.相反,该函数引用该变量.因此,当调用任何这些函数时,$(‘#box2’).text(new_info)将被解析为$(‘#box2’).text(“调用函数时new_info保持的值)”,而不是$( ‘#box2’).text(“创建函数时new_info持有的值”).只需在代码中添加第二个函数,即可为每个回调访问一个副本:
$(this).click((function(currentNewInfo)
{
return function()
{
$('#box2').text(currentNewInfo);
}
}(new_info)));
我在这里做的是创建一个函数,它接受一个参数,并立即调用它.我传递new_info作为参数,因此currentNewInfo的值将是new_info当时持有的值(也就是副本)
我调用的函数(IIFE – 或立即调用的函数表达式)返回实际的回调.在这个回调中,我没有引用new_info,而是引用了IIFE的参数:currentNewInfo.
因为每个函数都有自己的作用域,所以该变量是封闭的(因此名称为闭包),并且不能从外部访问或更改.唯一可以访问currentNewInfo变量的是IIFE返回的函数.
也许您担心名称冲突(您创建的每个回调都使用引用currentNewInfo),但事实并非如此:每个回调都是由单独的函数创建的,因此可以访问不同的范围.在不能相互访问的范围之间不可能存在名称冲突……只是为了让事情变得非常简单:
Where /\ and /\
|| ||
is return function() is scope of IIFE
因此,闭包在返回后可以访问函数的作用域.在将表达式解析为值时,该范围具有优先权.为了更好地理解这一点,这里有一个类似的图表,向您展示JS如何解析表达式:
每个粉红色的“外部环境记录”是一个函数的范围(已经返回的函数的闭包范围或当前正在调用的函数).最后一个环境将是全局对象,或者为null(在严格模式下).这里的所有都是它的.
老实说,关闭起初很困难,但是一旦你掌握了我试图在这里解释的内容,它们就会非常有趣.
Check this link我可以继续解释用例和优点以及嵌套闭包的工作方式,但我最终会写一本书.我发布的链接在解释闭包如何使用相当愚蠢的绘图方面做得很好.它可能看起来很幼稚,但是当我试图掌握lambda函数,闭包和范围的概念时,它们实际上对我有很大的帮助.上面的图表是从我链接到的页面中获取的,它更深入地解释了这些概念,但我仍然认为简单粗略的图纸非常自我解释.
其他问题:
正如有人指出的那样:“你有什么期望可以参考”.看一下片段,这将只引用全局对象(窗口),如果你问我,将相同/类似的事件处理程序附加到窗口根本没有意义.
全局变量是邪恶的,隐含的全局变量更是如此.我看不到new_info,也没有在任何地方声明myArray. JS解析表达式的方式有点令人遗憾,并且回归到创建全局变量,而不是窥视:
var bar = 666;//global, always evil
function createGlobal()
{
var local = 2;
foo = bar * local;
}
createGlobal();
我们来看看foo:
JS is in createGlobal scope: var local is declared, and assigned 2.
foo is used, and assigned bar*local
|| || \\=>found in current scope, resolves to 2
|| ||
|| \\=>found in global scope, resolves to 666
||
||
||=> JS looks for foo declaration in function scope first, not found
||
||=> moves up 1 scope (either higher function, or global scope)
||
\\=>Global scope, foo not found, create foo globally! - hence, implied global
\\
\\=>foo can now be resolved to global variable, value undefined
过多的DOM查询:您的事件处理程序回调都是这样的:
$('#box2').text(new_info);
这($(‘#box2’))实际上与编写document.getElementById(‘#box2’)相同.这实际上是英语.想想这样:每次客户点击$(this) – 无论可能是什么,你都在访问DOM,并扫描它以获得具有给定ID的元素.为什么不这样做一次并使用内存中的引用来更改文本.这可以节省无数的DOM查询.你可以使用一个变量,或者(根据我对闭包的解释),一个闭包:
var list = (function(box2, list, i)
{//list & i are arguments, so local to scope, too
for (i = 0; i < myArray.length; i++)
{
list += "<br>" + myArray[i].letter;//<-- don't know why you use this
//new_info = myArray[i].link; no need for this var
$(this).click((function(new_info)
{//new_info is closure var now
return function ()
{//box2 references DOM element, is kept in memory to reduce DOM querying
box2.text(link);
};
}(myArray[i].link));//instead of new_info, just pass value here
}
return list;//return string, assign to outer variable
}($('#box2'), ''));//query dom here, pass reference as argument
内容总结
以上是互联网集市为您收集整理的javascript – 如何使此代码工作?全部内容,希望文章能够帮你解决javascript – 如何使此代码工作?所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。