如何正确将JavaScript数组作为参数传入函数
核心错误点
addEventListener的第二个参数要求传入函数引用,浏览器触发对应事件时才会调用这个函数,且默认只会给回调函数传入1个参数:当前事件对象event。
你写的window.addEventListener('resize', changeGridFullScreen(heights), true)存在两个问题:
changeGridFullScreen(heights)是立即执行的函数调用,代码运行到这一行就会直接执行函数,把它的返回值(你的函数没有写return,返回undefined)传给addEventListener,resize触发时根本找不到要执行的回调。- 就算你传了函数引用,浏览器默认也只会传
event参数,不会自动把你自定义的minHeights数组传进函数。
正确实现方案
两种常用写法按需选择即可:
写法1:包装匿名函数(推荐,可读性最好)
用一个匿名函数作为回调传给addEventListener,resize触发时先执行这个匿名函数,在内部手动调用你的业务函数,把event和自定义参数都传进去:
function changeGridFullScreen(event, minHeights) { const bodyHeaderHeight = document.getElementById('body-header').clientHeight; const newHeight = window.innerHeight - bodyHeaderHeight; const fsClasses = document.getElementsByClassName("grid-full-screen"); for(let i = 0; i < fsClasses.length; i++){ if(newHeight >= minHeights[i]){ fsClasses[i].style.height = newHeight + "px"; } } } // 原函数名和内部变量重名,改名为getMinHeights避免混淆 function getMinHeights(){ const fsClasses = document.getElementsByClassName("grid-full-screen"); const minHeights = []; for(let i = 0; i < fsClasses.length; i++){ minHeights[i] = fsClasses[i].clientHeight; } return minHeights; } // 初始化时计算一次固定的最小高度,如果高度会动态变化,把这行挪到回调内部即可 const heights = getMinHeights(); window.addEventListener('resize', (event) => { changeGridFullScreen(event, heights); }, true);
如果页面运行过程中区块内容会变化、最小高度不固定,就把
const heights = getMinHeights()挪到上面的匿名回调函数内部,每次触发resize时重新计算最新的最小高度即可。
写法2:用bind预绑定参数
用Function.prototype.bind可以预先给函数填充参数,返回一个新的函数引用传给addEventListener。注意预绑定的参数会排在参数列表最前面,需要调整原函数的参数顺序:
// 注意参数顺序:预绑定的minHeights在前,浏览器自动传入的event在后 function changeGridFullScreen(minHeights, event) { const bodyHeaderHeight = document.getElementById('body-header').clientHeight; const newHeight = window.innerHeight - bodyHeaderHeight; const fsClasses = document.getElementsByClassName("grid-full-screen"); for(let i = 0; i < fsClasses.length; i++){ if(newHeight >= minHeights[i]){ fsClasses[i].style.height = newHeight + "px"; } } } function getMinHeights(){ const fsClasses = document.getElementsByClassName("grid-full-screen"); const minHeights = []; for(let i = 0; i < fsClasses.length; i++){ minHeights[i] = fsClasses[i].clientHeight; } return minHeights; } const heights = getMinHeights(); // bind第一个参数是函数内this的指向,不需要改this就传null,后面跟要预绑定的参数 window.addEventListener('resize', changeGridFullScreen.bind(null, heights), true);
额外注意点
- 循环计数变量建议用
let声明,不要用var,避免变量提升带来的作用域意外问题。 - 不要让函数名和函数内部的变量名重名,会大幅降低代码可读性,还容易引发意料之外的报错。
内容的提问来源于stack exchange,提问作者Boberwt
相关产品推荐
相关产品推荐

