jQuery 3中对象字面量内定义的.map()方法为何始终返回空数组?
解决自定义对象中jQuery方法获取DOM属性失效的问题
听起来你遇到的问题挺典型的——单独跑逻辑正常,塞进对象字面量就罢工,还碰到map返回空数组的情况。我帮你拆解下可能的原因和对应的解决方案:
一、先排查最常见的坑:DOM加载时机
JSFiddle默认会把代码放在DOM加载完成的回调里执行,但你的项目里可能没做这个处理。如果你的对象方法在页面DOM还没渲染完就被调用了,$('.portlet-body')根本找不到元素,自然返回空数组或者没数据。
解决方案:确保调用方法时DOM已经就绪
用jQuery的就绪事件包裹调用逻辑:
$(document).ready(function() { // 在这里调用你的对象方法 console.log(yourCustomObject.getPortletInfo()); });
或者用原生JS的DOM加载事件:
document.addEventListener('DOMContentLoaded', function() { yourCustomObject.getPortletInfo(); });
二、修正jQuery.map的使用姿势
你说map方法始终返回长度为0的数组,大概率是忘了jQuery的.map()和原生数组map的区别——jQuery的map返回的是jQuery包装集合,不是普通数组,必须调用.get()才能转换成真正的数组。
正确的map写法示例:
const yourCustomObject = { getPortletInfo: function() { return $('.portlet-body').map(function() { // 建议加个判断,避免找不到子div时出错 const $childDiv = $(this).find('div:first'); if ($childDiv.length === 0) return null; return { id: $childDiv.attr('id'), aspValue: $childDiv.data('asp') }; }).get(); // 关键:调用get()转成普通数组 } };
三、检查动态生成元素的情况
如果你的.portlet-body是通过AJAX加载、或者用JS动态渲染出来的,静态的$('.portlet-body')也会找不到元素。这种情况下:
- 要在元素渲染完成的回调里调用方法(比如AJAX的success回调、组件的mounted钩子)
- 或者用事件委托监听元素加载,但更推荐前者,性能更好
四、避免上下文混淆(箭头函数的锅)
如果你在对象方法里不小心用了箭头函数,会导致each或map里的this指向错误(指向对象本身,而不是当前DOM元素),自然找不到子元素。
错误示例:
const yourCustomObject = { getPortletInfo: () => { // 这里用了箭头函数,坑! const data = []; $('.portlet-body').each(() => { // 这里的this也不是DOM元素 const $childDiv = $(this).find('div'); // 找不到元素 data.push(...) }); return data; } };
修正:把对象方法和each/map里的回调都改成普通函数,保证this指向当前的.portlet-body元素。
快速验证方法
先在浏览器控制台手动执行$('.portlet-body').length:
- 如果返回0:说明DOM没加载完,或者元素是动态生成的,先解决这个问题
- 如果返回大于0:再检查方法里的选择器、map是否加了
.get()、上下文是否正确
内容的提问来源于stack exchange,提问作者user9306701
相关产品推荐
相关产品推荐

