JavaScript中子函数访问外部变量的3种解决方法

前言

我们在写web页面时,肯定会经常遇到下面这种情况:

<body>

<div class="btns-wrapper"></div>

<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script>
var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
 var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper);
 btn.on('click', function(evt){
  console.log('点击按钮:' + i);
 });
}
</script>

</body>

代码很简单,就是在页面上创建几个按钮,同时定义按钮的点击事件

可当点击按钮时,我们发现获取到的序号一直都是5,也就是 i 最后的值。

这是因为定义click事件时的匿名函数所引用的都是同一个变量 i

解决办法1:立即执行

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
 var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper);

 //默认方法
 //btn.on('click', function(evt){
 // console.log('点击按钮:' + i);
 //});

 //方法1:立即执行
 btn.on('click', (function(n){
  return function(evt){
   console.log('点击按钮:' + n);
  }
 })(i));

}

这种方式就是在定义事件时直接为每个按钮都创建了一个独立的匿名函数(闭包),并且每个函数都持有正确的 i 变量

解决办法2:利用jquery的事件传参

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
 var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper);

 //默认方法
 //btn.on('click', function(evt){
 // console.log('点击按钮:' + i);
 //});

 //方法2:利用JQuery的事件传参
 btn.on('click', { i: i }, function(evt){
  console.log('点击按钮:' + evt.data.i);
 });

}

这种办法就简单多了,直接利用jquery将参数体传递给匿名函数即可。

解决办法3:利用dom的data属性

var wrapper = $('.btns-wrapper');
for(var i = 0; i < 5; i++){
 var btn = $('<button>按钮' + i + '</button>').appendTo(wrapper);

 //默认方法
 //btn.on('click', function(evt){
 // console.log('点击按钮:' + i);
 //});

 //方法3:利用dom的data属性
 btn.data('i', i);
 btn.on('click', function(evt){
  console.log('点击按钮:' + $(this).data('i'));
 });

}

这种方法也很简单,弊端就是无法利用data属性定义结构化的数据。

总结

综合来看,如果是jquery环境,利用事件参数来转递变量是最简单的,而且可以传递结构化的数据。

否则只能通过立即执行(闭包)的方式。

到此这篇关于JavaScript中子函数访问外部变量的文章就介绍到这了,更多相关JS子函数访问外部变量内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • JavaScript闭包函数访问外部变量的方法

    闭包是指有权访问另一个函数作用域中的变量的函数,但作用域的配置机制有一个需要注意的地方,即闭包只能取得包含函数中任何变量的最后一个值. 如以下案例: function create(){     var arr = new Array();        for (var i=0; i<10; i++){         arr[i] = function(){             return i;         };      }       return arr; }   var c

  • JavaScript中子函数访问外部变量的3种解决方法

    前言 我们在写web页面时,肯定会经常遇到下面这种情况: <body> <div class="btns-wrapper"></div> <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <script> var wrapper = $('.btns-wrapper'); fo

  • javascript事件函数中获得事件源的两种不错方法

    在javascript的事件响应中,许多情况我们需要获得事件源对象来对其属性进行更改,比如更改img的src属性.在事件响应函数中获得事件源的方法有如下两种: 第一种: 直接把作为一个参数传入.例如 复制代码 代码如下: <div id="myid" onclick="show(this);">text</div> <script type="text/javascript"> function show(ob

  • javascript trim函数在IE下不能用的解决方法

    javascript 的trim 函数在firefox 下面使用没有问题 <script language="javascript"> var test1 = " aa "; test1 = test1.toString(); test1 = test1.trim(); </script> 在火狐下这样用没有问题, 但是在IE下就报错 那么我们可以修改一下 String.prototype.trim=function(){return thi

  • JavaScript中子对象访问父对象的方式详解

    在传统面向对象的编程语言里,都会提供一种子类访问父类的特殊语法,引文我们在实现子类方法往往需要父类方法的额外辅助.在这种情况下,子类通常会调用父类中的同名方法,最终以便完成工作. javascript虽然没有类似上述的特殊语法,但我们可以造一个啊! function her(){}; her.prototype.name = 'Anna'; her.prototype.toString = function(){ var const = this.constructor; return cons

  • Android4.4新增函数访问外部存储

    在Android 4.4系统中,外置存储卡(SD卡)被称为二级外部存储设备(secondary storage),应用程序已无法往外置存储卡(SD卡)写入数据,并且WRITE_EXTERNAL_STORAGE只为设备上的主要外部存储(primary storage)授予写权限,对于其他外部存储,其上的文件属性都改为基于文件夹结构,应用无需获取WRITE_EXTERNAL_STORAGE权限,但可以管理与自己包名相关的文件夹. 举例来说,如果应用的包名是com.example.externalst

  • javascript面向对象之访问对象属性的两种方式分析

    本文实例分析了javascript面向对象之访问对象属性的两种方式.分享给大家供大家参考.具体如下: javascript面向对象的访问对象属性的两种方式.如下代码所示: 复制代码 代码如下: <script language="javascript" type="text/javascript"> function Person(){}; var p1 = new Person(); p1.name="王美人"; document.

  • JavaScript监听手机物理返回键的两种解决方法

    JavaScript没有监听物理返回键的API,所以只能使用 popstate 事件监听. 有两个解决办法: 1.返回到指定的页面 pushHistory(); window.addEventListener("popstate", function(e) { window.location = 'http://www.baidu.com'; }, false); function pushHistory() { var state = { title: "title&quo

  • jquery与js函数冲突的两种解决方法

    如果您还有别的要求,想继续使用原先的$(),同时还需要与别的类库不冲突的话,还有两种解决方法 其一: 复制代码 代码如下: jQuery.noConflict(); jQuery(function($) { $("p").click(function() //在函数内继续可以使用jquery类库的$()方法 { alert($(this).text()); }) }) var JsCOM_cr = $("cr"); // 在函数外面,照样可以使用JsCOM.js的$

  • 基于php双引号中访问数组元素报错的解决方法

    最近在做微信公众号开发,在一个发送图文接口中,需要把数组元素拼接在XML字符串中 foreach ($itemArr as $key => $value){ $items .= "<item> <Title><![CDATA[$value['title']]]></Title> <Description><![CDATA[[$value['description']]]></Description> <

随机推荐