为什么createTags内const声明的tags数组可修改且能留存历史输入?
JS代码相关疑问解答
相关代码
textarea.addEventListener('keyup', (e) => { createTags(e.target.value) }) const createTags = (input) => { const tags = input.split(',').filter(tag => tag.trim() !== '').map(tag => tag.trim()) console.log(tags) }
输出结果
["t"] ["te"] ["tes"] ["test"] ["test"] ["test", "t"] ["test", "te"] ["test", "tes"] ["test", "test"] ["test", "test"]
疑问逐一解答
- 为什么可以逐字符将输入内容赋值给tags数组?
每次keyup事件触发时,拿到的e.target.value是textarea输入框内当前全部的输入内容,不是本次输入的单个字符。比如你敲第一个字符t时value是t,敲第二个字符e时value已经变成了te,每次split(',')切割的都是当前完整的输入值,所以生成的tags数组自然会跟着输入逐字符变长,不是逐字符追加赋值,是每次都用全量输入重新生成数组。 - createTags函数是如何记住之前的输入内容的?
这个函数本身没有存储任何历史输入内容,存储之前输入的是textarea DOM元素的value属性。所有你输入的内容都会实时保存在textarea的value里,每次keyup触发只是把当前的全量value传给createTags处理,函数执行完内部的局部变量就销毁了,没有记忆能力。你看到输出里出现两个元素的数组,是你输入了逗号之后,全量value变成了test,xxx格式,切割后自然得到两个元素,完全是输入框自己存储了所有内容。 - 为什么能够修改const声明的数组?
你的代码里完全没有修改const声明的数组,这个误解来自两个点:
- 每次执行createTags函数时,都会在当前函数作用域内重新声明一个局部的
const tags变量,和之前执行时的tags完全是两个独立的变量,函数执行结束后这个变量就被回收,不存在修改之前const变量的情况。 - const的约束是变量的引用地址不能修改,不是引用指向的内容不能修改。比如
const arr = []时,你可以用arr.push(1)修改数组的内容,但是不能用arr = [1,2]给arr重新赋值新的数组引用,后者才会触发const的报错。你代码里用split、filter、map生成的是全新的数组,直接赋值给当次的局部tags变量,完全符合const的使用规则。
内容的提问来源于stack exchange,提问作者IIIllllIIII
相关产品推荐
相关产品推荐

