JavaScript函数传参问题:JSON生成列表点击时变量未定义报错
解决内联onclick中变量未定义的问题
这个坑我之前踩过,咱们先搞清楚为啥会报错:
你循环里的s是newList函数的局部变量,alert能正常打印是因为此时函数还在执行,变量还活着。但当你用字符串拼接生成<li onclick="myFunction(s)">的时候,这个s并不会被替换成实际的变量值——最终生成的HTML代码里就是字面量s,当你点击元素时,浏览器会去全局作用域找这个s,而全局里根本没有定义它,自然就抛出ReferenceError了。
下面给你三种靠谱的解决方案,推荐第一种:
方案一:用jQuery事件绑定替代内联onclick(最推荐)
放弃内联事件写法,直接用jQuery的.on()方法绑定点击事件,利用闭包特性保留s的当前值:
dataObject.forEach(newList); function newList(item, index) { var s = item.time; alert(s); // 先创建li元素,不写内联onclick var list = $('<li>' + listItemString + '</li>'); // 绑定点击事件,这里能直接访问到当前循环的s list.on('click', function() { myFunction(s); }); // 别忘把生成的li添加到目标列表里,比如: // $('#your-ul-id').append(list); }
这种写法更符合现代JS规范,也避免了作用域混乱,后期维护起来更方便。
方案二:利用data属性存储值
把s的值存在li元素的自定义data属性里,点击时再读取这个值:
dataObject.forEach(newList); function newList(item, index) { var s = item.time; alert(s); // 将s存入data-time属性,同时在onclick里读取这个属性值 var list = $('<li onclick="myFunction(this.getAttribute(\'data-time\'))" data-time="' + s + '">' + listItemString + '</li>'); // 或者用jQuery的data方法更简洁: // var list = $('<li>' + listItemString + '</li>') // .data('time', s) // .on('click', function() { // myFunction($(this).data('time')); // }); }
方案三:用闭包包裹变量(适合理解作用域原理)
如果一定要用内联onclick,可以用立即执行函数(IIFE)把当前的s值“固定”下来,避免后续循环覆盖:
dataObject.forEach(newList); function newList(item, index) { var s = item.time; alert(s); // 用立即执行函数捕获当前的s值,生成对应的myFunction调用代码 var list = $('<li onclick="' + (function(currentTime) { // 用JSON.stringify处理字符串转义,避免引号冲突 return 'myFunction(' + JSON.stringify(currentTime) + ')'; })(s) + '">' + listItemString + '</li>'); }
内容的提问来源于stack exchange,提问作者j.doe
相关产品推荐
相关产品推荐

