【问题标题】:How to solve Javascript Cycle reference?如何解决 Javascript 循环参考?
【发布时间】:2021-12-28 05:21:56
【问题描述】:

第一个代码

HTML

<div>
    <select class="a">
        <option value="1">aaa</option>
        <option value="2">bbb</option>
    </select>
    <input class="b">
</div>

A.js

const a =  (function initA() {
    const a = document.querySelector('select.a');

    a.addEventListener('change', function() {
        b.setValue(this.value);
    })

    return {
        value: () => a.value
    }
})()

const b =  (function initB() {
    const b = document.querySelector('input.b');

    b.addEventListener('keyup', function (){
        if (this.value.startsWith(a.value()) === false) {
            b.value = a.value();
        }
    })

    return {
        setValue: function (val) {
            b.value = val;
        }
    }
})()

当select改变时用select值初始化输入值的事件,如果输入值不是以select值开头的,就用select值初始化。

我以为它会在很多地方使用,所以我将代码移动并模块化。

Common.js

export function initA() {
    const a = document.querySelector('select.a');

    a.addEventListener('change', function() {
        b.setValue(this.value);
    })

    return {
        value: () => a.value
    }
}

export function initB() {
    const b = document.querySelector('input.b');

    b.addEventListener('keyup', function (){
        if (this.value.startsWith(a.value()) === false) {
            b.value = a.value();
        }
    })

    return {
        setValue: function (val) {
            b.value = val;
        }
    }
}

A.js

const a = initA();
const b = initB();

但是会发生Uncaught ReferenceError

const a = initA(b);
const b = initB(a);

赋予变量也是如此。

如何解决问题?

【问题讨论】:

  • const 不会像var 那样得到hoisted,如果在初始化之前读取它会抛出一个ReferenceError。您可以向initAinitB 添加参数以传递引用的元素。

标签: javascript hoisting


【解决方案1】:

由于select 需要input 才能正常工作,反之亦然,我将这两个函数合并为一个。您的两个功能都不是真正独立的。此外,我更喜欢传递元素而不是假设 select.ainput.b

function initAB(a, b){
  if(a && b){
    a.addEventListener('change', function(b) {
      b.value = this.value
    }.bind(a, b));
    
    b.addEventListener('keyup', function (a){
      if (this.value.startsWith(a.value) === false) {
        b.value = a.value;
      }
    }.bind(b, a));
    
    return true
  };
  
  return false
};

initAB(
  document.querySelector('select.a'),
  document.querySelector('input.b')
);
<div>
    <select class="a">
        <option value="1">aaa</option>
        <option value="2">bbb</option>
    </select>
    <input class="b">
</div>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 2022-06-15
    • 1970-01-01
    • 2014-02-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多