javascript - 使用 switch case,case 内部的 break 结束了外部 for...of 循环迭代
问题描述
我定义了以下函数并在其上运行DOMContentLoaded
(其中不相关):
function dependentControls() {
const dependers = [...document.querySelectorAll('[data-depends-on]')]
for (const depender of dependers) {
let dependency = document.getElementById(depender.dataset.dependsOn)
if (dependency) {
let dependencyDetails = {
prop: null,
state: null
}
switch (dependency.type) {
case 'checkbox':
{
dependencyDetails.prop = 'checked'
dependencyDetails.state = false
break // this break exits the current for loop iteration
}
case 'text':
{
dependencyDetails.prop = 'value'
dependencyDetails.state = ''
break // this break exits the current for loop iteration
}
default:
console.log('default case')
}
console.log("switch...end") // this line is never reached
depender.disabled = !dependency[dependencyDetails.prop]
dependency.addEventListener('change', () => {
console.log('dependancy changed')
depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state
})
}
}
console.log('for...end')
}
document.addEventListener('DOMContentLoaded', dependentControls);
<div>
<input type="checkbox" id="fooBar" />
<label for="fooBar">dependency</label>
</div>
<hr />
<div>
<label for="fooBaz">depender</label>
<input type="text" id="fooBaz" data-depends-on="fooBar" value="depender" />
</div>
这是转译代码的相关部分:
function _toConsumableArray(arr) {
if (Array.isArray(arr)) {
for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) {
arr2[i] = arr[i];
}
return arr2;
} else {
return Array.from(arr);
}
}
var dependentControls = function dependentControls() {
var dependers = _toConsumableArray(document.querySelectorAll('[data-depends-on]'));
var _iteratorNormalCompletion5 = true;
var _didIteratorError5 = false;
var _iteratorError5 = undefined;
try {
var _loop5 = function _loop5() {
var depender = _step5.value;
var dependency = document.getElementById(depender.dataset.dependsOn);
if (dependency) {
var dependencyDetails = {
prop: 'checked',
state: false
};
switch (dependency.type) {
case 'checkbox':
{
dependencyDetails.prop = 'checked';
dependencyDetails.state = false;
return "break";
}
case 'text':
{
dependencyDetails.prop = 'value';
dependencyDetails.state = '';
return "break";
}
default:
}
console.log("switch...end"); // this line is never reached
depender.disabled = !dependency[dependencyDetails.prop];
dependency.addEventListener('change', function() {
depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state;
});
}
};
_loop4: for (var _iterator5 = dependers[Symbol.iterator](), _step5; !(_iteratorNormalCompletion5 = (_step5 = _iterator5.next()).done); _iteratorNormalCompletion5 = true) {
var _ret2 = _loop5();
switch (_ret2) {
case "break":
break _loop4;
default:
if (_typeof(_ret2) === "object") return _ret2.v;
}
}
} catch (err) {
_didIteratorError5 = true;
_iteratorError5 = err;
} finally {
try {
if (!_iteratorNormalCompletion5 && _iterator5.return != null) {
_iterator5.return();
}
} finally {
if (_didIteratorError5) {
throw _iteratorError5;
}
}
}
console.log("for...end");
}
document.addEventListener('DOMContentLoaded', dependentControls);
<div>
<input type="checkbox" id="fooBar" />
<label for="fooBar">dependency</label>
</div>
<hr />
<div>
<label for="fooBaz">depender</label>
<input type="text" id="fooBaz" data-depends-on="fooBar" value="depender" />
</div>
这是我的.babelrc
:
{
"presets": [
[ "@babel/preset-env", {
"targets": {
"browsers": [ "last 2 versions", "ie >= 11" ]
}
}]
]
}
我正在使用 Babel 7 来编译代码并使用最新的 webpack 来捆绑它。当我将此代码粘贴到控制台并调用该函数时,问题不会发生。当我将此代码粘贴到http://babeljs.io/repl并将生成的代码粘贴到控制台时,它也可以工作。
从表面上看,这已经在 4 月份被报道了,到目前为止还没有人评论这个问题:
https://github.com/babel/babel/issues/7765
尽管如此,我也提交了它:
解决方案
事实证明,这确实是 Babel 7 中引入的一个错误。
它在 Babel REPL 中无法重现的原因是官方的 REPL 仍在 Babel 6.2.6 上。7.0 REPL 目前可在此处获得:
Babel 7 转换break
为return "break";
如果break
发生在case
用花括号括起来的块中:
这与 Babel 7 的预期一致:
switch (a) {
case 1:
/** some code **/
break
default:
}
这就产生了问题:
switch (a) {
case 1: { // <-- wrapping the case ...
/** some code **/
break
} // <-- ... makes Babel go wrong
default: {}
}
将箱子包裹起来 {}
会使 Babel 转换break
为return "break";
- 这显然是 Babel 方面的一个错误。
临时解决方案:
如果不需要的话,暂时不要将case
指令包装在新{}
的块上下文中(我的原始代码中的新块上下文只是为了可读性,所以无论如何都没有必要)。将在 Babel 修复该问题后更新答案。
推荐阅读
- android - Flutter 位置包帮助:我想将用户证明的坐标提取到单独的 var/string 或 double 中
- video - ffmpeg 分布式转码
- julia - 从压缩 Q 中恢复 Q(spqr,以稀疏方式)
- r - 通过 R 中的 barplot() 函数在分组的 barplot 中绘制误差线
- swift - 为什么我可以创建静态变量的实例?
- css - 样式化组件关键帧动画不适用于 React 组件
- java - javap结果中的重复方法
- javascript - 将表情符号插入 Angular 的输入字段
- php - 如何在 laravel 中使用 ajax 成功插入数据库?
- python - 转换后 TFLite 模型中缺少层