为什么 JavaScript 的这两部分不等价?

2024-03-24

在 jquery 1.4.2、ff 3.6.6 中:

以下代码生成三个 div,它们按照您的预期将消息写入 Firebug 控制台。但是,如果您取消注释循环并注释掉手动执行的 3 行,则它将不起作用 - 将鼠标悬停在任何 div 上都会导致"three"被写入控制台。

为什么这两种方法有什么不同?在每个元素中,您都使用选择器来查找元素并向其添加事件。

<head>
<script type="text/javascript" src="/media/js/jquery.js"></script>
<script>

$( document ).ready( function() {

  $("#one").mouseenter(function(){console.log("one")})
  $("#two").mouseenter(function(){console.log("two")})
  $("#three").mouseenter(function(){console.log("three")})

  //  names=['one','two','three'];
  //  for (k in names){
  //    id=names[k]
  //    $("#"+id).mouseenter(function(){console.log(id)})
  //  }
})
</script>
</head>

<body>
  <span id="one">ONE</span>
  <p><span id="two">TWO</span></p>
  <p><span id="three">THREE</span></p>
</body>

你将会有一个非常常见的闭包问题 https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures#Creating_closures_in_loops.3a_A_common_mistake in the for in loop.

封闭在闭包中的变量共享同一个环境,所以到了mouseenter回调被调用,循环将运行它的过程并且id变量将指向最后一个元素的值names array.

如果您不熟悉闭包的工作原理,这可能是一个相当棘手的话题。您可能需要查看以下文章以获取简要介绍:

  • Mozilla 开发中心:使用闭包 https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Working_with_Closures

您可以使用函数工厂通过更多闭包来解决此问题:

function makeMouseEnterCallback (id) {  
  return function() {  
    console.log(id);
  };  
}

// ...

var id, k,
    names = ['one','two','three'];

for (k = 0; k < names.length; k++) {
  id = names[k];
  $("#" + id).mouseenter(makeMouseEnterCallback(id));
}

您还可以按如下方式内联上述函数工厂:

var id, k, 
    names = ['one','two','three'];

for (k = 0; k < names.length; k++) {
  id = names[k];
  $("#" + id).mouseenter((function (p_id) {  
    return function() {  
      console.log(p_id);
    };  
  })(id));
}

任何另一种解决方案都可以是@d.m 在另一个答案中建议 https://stackoverflow.com/questions/3287500/why-arent-these-two-bits-of-javascript-equivalent-jquery/3287561#3287561,将每个迭代包含在其自己的范围内:

var k, 
    names = ['one','two','three'];

for (k = 0; k < names.length; k++) {
  (function() {
    var id = names[k];
    $("#" + id).mouseenter(function () { console.log(id) });
  })();
}

虽然与此问题无关,但通常建议避免使用for in循环迭代数组的项目,如@CMS https://stackoverflow.com/users/5445/cms在下面的评论中指出(进一步阅读 https://stackoverflow.com/questions/3010840/loop-through-array-in-javascript)。此外,在 JavaScript 中,用分号显式终止语句也被认为是一种很好的做法。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 JavaScript 的这两部分不等价? 的相关文章

随机推荐

  • 托管 C++/CLI 类中的 auto_ptr 或 shared_ptr 等效项

    在 C CLI 中 您可以在托管类中使用本机类型 因为不允许在托管类中保存本机类的成员 在这种情况下您需要使用指针 这是一个例子 class NativeClass public ref class ManagedClass private
  • Discord.js v14 创建频道

    我尝试创建一个频道 但总是出现错误 我不知道如何解决它 不要注意 req 0 在 代码 中 它来自数据库 与问题没有链接 因为它在 v13 中工作 看来您的帖子主要是代码 请添加更多详细信息 我不知道我能得到什么更多的细节 哈哈 抱歉 英语
  • 在 Node.js 中的单个 HTTP 请求中调用多个 HTTP 请求

    我试图在单个 URL 调用中调用多个 URL 并将其 json 响应推送到数组中 然后将该数组发送给最终用户 我的代码如下所示 var express require express var main router express Rout
  • 我有一个 JApplet,它必须显示 3 个组件。 (2 个 JPanel 和 1 个 Paint 方法)

    我有一个作业 其中我必须允许用户使用二次方程绘制图表 我设法绘制了图形的骨架 现在我尝试显示 控制面板 以供用户输入值 我有4个文件 graph java panel java panelB java panelC java 我的问题是当我
  • 如何在 debian 上安装 apcu 作为 php7 扩展

    我看过这个ubuntu教程 http thereluctantdeveloper com 2015 12 quick and dirty php 70 set up on ubuntu 1404 with apcu http therelu
  • SQL Server 执行模拟

    两者有什么区别 execute as user testuser AND execute as login testuser 我正在这些登录名下执行跨数据库过程 它适用于作为登录名执行 但不适用于作为用户执行 这表示服务器主体 testus
  • 编译为 C 时的垃圾收集

    将垃圾收集语言编译为C时 垃圾收集的技术有哪些 我知道有两个 维护一个影子堆栈 将所有根显式保存在数据结构中 使用像 Boehm 这样的保守垃圾收集器 第一种技术很慢 因为您必须维护影子堆栈 可能每次调用函数时 您都需要将局部变量保存在数据
  • 如何使用 jQuery 获取 id 元素的一部分?

    如何从 id old id 的 span 中获取 一些文本 并将其放入 id new id 中 span Some text span span span span Some text span span span 我不知道如何获得数字部分
  • 4 层(对于 N 层)架构示例?

    最近 我的一个朋友向我询问 N 层架构 我能够通过示例向他解释 1 2 和 3 层架构 但当我想给出超过 3 层的例子时 我就陷入了困境 我用谷歌搜索并大量寻求帮助 但找不到任何像样的例子 事实上 它被命名为 N 层 这让我认为 N 可以是
  • 使用升压间隔_map

    试图遵循boost party我制作了这个示例代码 include boost icl interval hpp include boost icl interval map hpp include
  • 为什么Python中列表元素查找的复杂度是O(1)?

    今天在课堂上 我们了解到从列表中检索元素是O 1 在Python中 为什么会这样呢 假设我有一个包含四个项目的列表 例如 li perry 1 23 5 s 这些项目在内存中具有不同的大小 所以不可能获取内存位置li 0 并添加每个元素大小
  • 相似列出现的次数

    我是 SQL SERVER 新手 需要您的建议 我有一张大桌子 上面有商店信息 这是 bench id 列 bench id 31 51 51 61 61 61 71 71 我创建了另一个包含两列的小表 distinct bench num
  • BatchGetItem 或 Query DynamoDb - 按范围查询

    我有一个名为 User 的表 它有一个用户 ID 的哈希键和一个组织 ID 的范围键 如何返回组织 ID 为 3 的所有用户 顺便说一句 这是一个 Lambda 函数 这段代码给了我一个错误 console log Loading even
  • YUY2 与 YUV 422

    我无法理解两者之间的确切区别 从研究来看 更多地讨论两者是不同的 但少数人似乎将它们分组在 4 2 2 抽样方案下 YUV 422 I 和 J 版本 有一个亮度平面 Y 和 2 个色度平面 U V 然而 在 I422 中 色度平面 蓝色和红
  • 如何在 React.js 中解析 FOUC

    我已经从 create react app 构建了react js 网站 但在生产模式下 存在 FOUC 因为样式是在 html 渲染后加载的 有什么办法可以解决这个问题吗 我一直在谷歌搜索答案 但还没有找到合适的答案 FOUC FOUC
  • 如何在WPF中绘制平滑的曲线?

    我有三个已知位置 目前我正在驾驶两条线路 如下所示 Line line new Line StrokeThickness 3 Stroke lineColor X1 MyX Y1 MyY X2 MyX Y2 MiddleY Graph Ch
  • Canvas 绘制在 Safari 上需要花费大量时间,但在 Chrome 或 FF 上则不需要

    我正在我的网站上制作万花筒 它所做的只是获取一张图像 通过拖放或加载时的默认图像 并将其复制 10 次 万花筒的每个切片复制一次 鼠标移动时 调整切片的旋转和缩放以达到所需的效果 在 Google Chrome 和 Firefox 上 它可
  • Azure 上的 ASP.NET MVC 5:对于 SVG 文件,“您正在查找的资源已被删除...”

    我创建了一个包含一些视图和控制器的 MVC 5 网页 添加了一些图像 gif 和 svg 并验证它主要在本地工作 图像显示出来 一切都按预期进行 当我部署到 Azure 时 gif 图像加载正常 但 svg 图像给出错误The resour
  • Javascript 如果对象中存在值?

    我有一个对象 var car company Honda year 2011 Model Brio 我想知道是否存在继承方法 这是正确的短语吗 来检查给定对象中是否存在值 有点像x hasOwnProperty or if x in car
  • 为什么 JavaScript 的这两部分不等价?

    在 jquery 1 4 2 ff 3 6 6 中 以下代码生成三个 div 它们按照您的预期将消息写入 Firebug 控制台 但是 如果您取消注释循环并注释掉手动执行的 3 行 则它将不起作用 将鼠标悬停在任何 div 上都会导致 th