addEventListener调用console.log()失败?浅谈函数调用

本文探讨了JavaScript中作为回调函数参数的正确使用方法,重点分析了如何传递带有外部参数的函数,以及直接传递函数名与匿名函数的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

引入

var dom = document.getElementByID("foo");
dom.addEventListener("click", console.log("hello"));

这一段代码是无法为”foo”对象绑定console.log函数,要用js实现此效果,要构建一个函数作为addEventListener的参数,如下所示

dom.addEventListener("click", function() {console.log("hello");});

或者

dom.addEventListener("click", () => {console.log("hello");});

=> 一个Arrow functions,详情见MDN文档箭头函数 - JavaScript | MDN
要直接地绑定,只能

dom.addEventListener("click", console.log);

注意此处的console.log不带括号
但是

<button id="foo" onclick="console.log(123)">foo<button>

却可以顺利地为foo绑定。js中还有很多需要函数作为输入参数情况,如setInterval(),也会发生类似结果。

问题的抽象

把所有需要函数作为参数地函数都简化成callback(args)函数

var callback = function(args) {
    args()
}

正常地使用

callback(foo);

如果foo的参数需要在callback外传入呢,此处将outside传入foo,再用callback调用foo(outside)

callback(() => foo(outside));//work
callback(foo(outside));//doesn't work

原因

1. foo(outside)没有合适的返回值

callback(foo(outside))会先执行foo(outside),再取返回值作为callback(args)地参数。
在这种情况下可以等效成

var mid = foo(outside);
callback(mid);

如果有合适的返回值,也可以传foo(x)

var proxy = function(x) {
    return foo(x);
}
callback(proxy(outside));

2. 传函数名和匿名函数都能作为参数

console.log和callback, foo, proxy一样,都是函数名,callback(函数名)是没问题地。proxy返回了匿名函数,和callback(function() {})或者callback(() => {})一样,所以也是有效的。

总结

如果要传foo(outside),传递匿名函数给callback

callback(() => foo(outside));

也可以设计一个这样的callback

var callback = (f, args) => { f(args); };
callback(foo, outside);

callback接收了outside,在内部使用outside调用了foo

<script> document.addEventListener('DOMContentLoaded', () => { // 接收参数 const queryString = window.location.search; const urlParams = new URLSearchParams(queryString); const deviceIds = urlParams.get('deviceId'); console.log('接收参数deviceId:',deviceIds) const tableBody = document.querySelector('#timed-load-table tbody'); let dataRows = []; // 用于存储表格数据的数组 const deviceId = new URLSearchParams(window.location.search).get('deviceId'); // 从URL获取deviceId参数 const populateTable = () => { // 清空表格内容 tableBody.innerHTML = ''; // 根据dataRows数组重新填充表格 dataRows.forEach(rowData => { const dateTime = rowData[0].dateTime ?? ''; const ratedVoltage = rowData[0].ratedVoltage ?? ''; const currentRating = rowData[0].currentRating ?? ''; const frontMachineA = rowData[0].frontMachineA ?? ''; const frontMachineB = rowData[0].frontMachineB ?? ''; const frontMachineC = rowData[0].frontMachineC ?? ''; const rearMachineA = rowData[0].rearMachineA ?? ''; const rearMachineB = rowData[0].rearMachineB ?? ''; const rearMachineC = rowData[0].rearMachineC ?? ''; const voltage = rowData[0].voltage ?? ''; const leakageResistance = rowData[0].leakageResistance ?? ''; const temperature = rowData[0].temperature ?? ''; const shake = rowData[0].shake ?? ''; const row = document.createElement('tr'); row.innerHTML = ` <td>${dateTime}</td> <td>${ratedVoltage}</td> <td>${currentRating}</td> <td>${frontMachineA}</td> <td>${frontMachineB}</td> <td>${frontMachineC}</td> <td>${rearMachineA}</td> <td>${rearMachineB}</td> <td>${rearMachineC}</td> <td>${voltage}</td> <td>${leakageResistance}</td> <td>${temperature}</td> <td>${shake}</td> `; tableBody.appendChild(row); }); }; const updateTable = async () => { httpApi("get", 'ThirdPartyInterfaces/beforeReadWrite/juBu.ashx',{ action:'nowData', deviceId:deviceIds, },{}).then(resp => { if(resp.status == "success"){ console.log('实时表格以及实时折线图------:',resp); const newData = resp.rows; if (newData) { // 将新数据添加到数组 dataRows.push(newData); // 如果数据超过限制 if (dataRows.length > 20) { dataRows.shift(); } // 重新填充表格 populateTable(); } }else{ alert(resp.message); } }).catch(error => { console.error('error:',error); }); }; // 每秒调用一次updateTable函数 // setInterval(updateTable, 1000); // 初始调用以立即填充数据(可选) updateTable(); }); </script> </body> </html> 错误:now.html?deviceId=65a91e07-cafd-cb52-e1de-079ff37d325e:163 error: TypeError: Cannot read properties of undefined (reading ‘dateTime’) 怎么解决
03-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值