解决let变量重复声明错误:如何定位变量重定义位置?
问题分析与解决
错误本质
你遇到的Uncaught SyntaxError: redeclaration of let/const xxx错误,核心原因是同一个作用域内重复声明了同名的let/const变量。因为let和const是块级作用域变量,且不允许在同一作用域内重复声明,哪怕前后用的是let和const混合声明也不行。
排查方向
1. 代码被重复渲染(最可能的原因)
你的代码是Shopify section模板中的script,当以下情况发生时,这段script会被多次输出到页面:
- 该section在页面中被添加了多个实例(比如页面里重复插入了同一个推荐模块section)
- 模板中的循环逻辑(比如
{% for ... %})错误地包裹了这段script,导致代码被循环输出
哪怕你只保留let sectionSelector = '#shopify-section-{{ section.id }}';这一行,只要这段script被渲染多次,每次执行都会在全局作用域声明同一个变量,第二次执行就会触发重声明错误。
2. 全局作用域存在同名变量
检查页面其他script标签中,是否也声明了sectionSelector或collectionSelectors变量,且这些script和当前代码处于同一作用域(比如都在全局)。
解决方法
方法1:用IIFE隔离作用域(快速解决)
把代码包裹在立即执行函数里,为每次script执行创建独立的作用域,避免全局变量冲突:
(function() { const sectionSelector = '#shopify-section-{{ section.id }}'; let collectionSelectors = document.querySelectorAll(`${sectionSelector} .recommendations__collection-selector`); for (let collectionSelector of collectionSelectors) { let blockId = collectionSelector.dataset.blockId; let collectionCarousel = document.querySelector(`${sectionSelector} .recommendations__collection[data-block-id="${blockId}"]`); let otherCarousels = document.querySelectorAll(`${sectionSelector} .recommendations__collection:not([data-block-id="${blockId}"])`); collectionSelector.addEventListener('click', () => { for (let otherCarousel of otherCarousels) { otherCarousel.classList.remove('active'); } for (let collectionSelector of collectionSelectors) { collectionSelector.classList.remove('active'); } collectionSelector.classList.add('active'); collectionCarousel.classList.add('active'); window.dispatchEvent(new Event('resize')); }) } })();
方法2:修复模板渲染逻辑
检查Shopify模板代码,确保这段script只被渲染一次:
- 确认section没有在页面中被重复添加
- 检查是否有循环逻辑错误地包含了这段script,把script移到循环外部
方法3:封装成独立函数
把初始化逻辑封装成函数,通过参数传递section ID,彻底避免全局变量:
function initRecommendations(sectionId) { const sectionSelector = `#shopify-section-${sectionId}`; let collectionSelectors = document.querySelectorAll(`${sectionSelector} .recommendations__collection-selector`); for (let collectionSelector of collectionSelectors) { // 原逻辑不变 } } // 调用函数 initRecommendations('{{ section.id }}');
关于for...of循环的误解
你怀疑循环导致错误是不对的:for...of循环中用let collectionSelector声明的变量,属于每次迭代的独立块级作用域,和外层的collectionSelectors或其他变量不会产生重声明冲突,问题和循环本身无关。
内容的提问来源于stack exchange,提问作者Tom Hanks
相关产品推荐
相关产品推荐

