代码之家  ›  专栏  ›  技术社区  ›  connexo

使用switch case,case内部的中断结束循环迭代的外部for

  •  4
  • connexo  · 技术社区  · 6 年前

    我定义了以下函数并在其上运行 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);
    <部门>
    <label for=“fooBar”>相关性</label>
    </div>
    <hr/>
    <div>
    <label for=“fooBaz”>依赖项</label>
    <input type=“text”id=“fooBaz”数据取决于=“fooBar”value=“depender”/>

    这是我的 .babelrc :

    {
      "presets": [
        [ "@babel/preset-env", {
          "targets": {
            "browsers": [ "last 2 versions", "ie >= 11" ]
          }
        }]
      ]
    }
    

    我用巴别7来传输代码和最新的网页包来捆绑它。当我将此代码粘贴到控制台并调用函数时,问题不会出现。当我粘贴代码时 http://babeljs.io/repl 并将生成的代码粘贴到控制台中,它也可以工作。

    从表面上看,这已经在4月份报道过了,到目前为止还没有人对此发表评论:

    https://github.com/babel/babel/issues/7765

    尽管如此,我还是提交了:

    https://github.com/babel/babel/issues/8709

    2 回复  |  直到 6 年前
        1
  •  2
  •   connexo    6 年前

    原来这真的是巴别塔7中引入的一个bug。

    它不能在巴别塔REPL中复制的原因是官方REPL仍然在巴别塔6.2.6上。7.0 REPL目前可从以下位置获得:

    https://babeljs.io/repl/build/master

    Babel 7透明胶片 break return "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: {}
    }
    

    把箱子包起来 {} 使巴贝尔透明 返回“break”; -显然是巴别塔那边的一只虫子。

    只是不要包装 案例 {} 现在,如果您不需要的话(我的原始代码中的新块上下文只是为了可读性,所以没有必要)。等巴贝尔修好了再更新答案。

        2
  •  0
  •   rafaelcastrocouto    6 年前

    代码运行正常 console.log("switch end") 按预期执行。

    确保你的巴别塔版本已更新。

    您可以在这里查看它的工作情况: https://codepen.io/rafaelcastrocouto/pen/LJrRqj

    'use strict';
    
    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); } }
    
    function dependantControls() {
      var dependers = [].concat(_toConsumableArray(document.querySelectorAll('[data-depends-on]')));
      var _iteratorNormalCompletion = true;
      var _didIteratorError = false;
      var _iteratorError = undefined;
    
      try {
        var _loop = function _loop() {
          var depender = _step.value;
    
          var dependency = document.getElementById(depender.dataset.dependsOn);
          if (dependency) {
            var 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 gets never executed!
            depender.disabled = !dependency[dependencyDetails.prop];
            dependency.addEventListener('change', function () {
              console.log('dependancy changed');
              depender.disabled = dependency[dependencyDetails.prop] === dependencyDetails.state;
            });
          }
        };
    
        for (var _iterator = dependers[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
          _loop();
        }
      } catch (err) {
        _didIteratorError = true;
        _iteratorError = err;
      } finally {
        try {
          if (!_iteratorNormalCompletion && _iterator.return) {
            _iterator.return();
          }
        } finally {
          if (_didIteratorError) {
            throw _iteratorError;
          }
        }
      }
    
      console.log('for...end');
    }
    
    document.addEventListener('DOMContentLoaded', dependantControls);
    <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>
    推荐文章