Mie*_*oli 17 javascript arrays svelte
我正在学习 Svelte,并在文档中阅读了需要重新分配数组才能让组件或页面更新它的文档。为此,他们设计了一个更惯用的解决方案。而不是写:
messages.push('hello');
messages = messages;
Run Code Online (Sandbox Code Playgroud)
你可以写:
messages = [...messages, 'hello'];
Run Code Online (Sandbox Code Playgroud)
不错,有道理 但随后文档说:
您可以使用类似的模式来替换 pop、shift、unshift 和 splice。
但是如何?我看不到如何从数组中删除项目。更重要的是,我怎样才能更地道地写出以下内容?
messages.splice(messages.indexOf('hello'), 1);
messages = messages;
Run Code Online (Sandbox Code Playgroud)
Tho*_*lle 17
例如,您可以使用过滤器数组方法创建一个没有元素的新数组'hello':
messages = messages.filter(m => m !== 'hello');
Run Code Online (Sandbox Code Playgroud)
Mic*_*nis 11
如前所述,Svelte 的反应性是由分配触发的。在当前斯维尔特教程使用JavaScript的(ES6)扩展的语法(三个点)到下一个更高的数目添加到一个数组,提供比使用冗余分配一个更惯用的溶液push:
function pushNumber() {
numbers = [...numbers, lastnumber]; // 1, 2, 3, 4, 5
}
Run Code Online (Sandbox Code Playgroud)
你可以使用传播语法来代替 pop, shift, unshift 并且 splice虽然它可能会增加在某些情况下操作的时间和复杂性:
function unshiftNumber() {
numbers = [firstnumber, ...numbers]; // 0, 1, 2, 3, 4
}
function popNumber() {
numbers = [...numbers.slice(0,numbers.length - 1)]; // 1, 2, 3
}
function shiftNumber() {
numbers = [...numbers.slice(1,numbers.length)]; // 2, 3, 4
}
function spliceNumber() {
numbers = [firstnumber, ...numbers.slice(0,numbers.length-1)];// 0, 1, 2, 3
}
Run Code Online (Sandbox Code Playgroud)
不过,传播只是一种方法。不使用 pop/push 等的目的是鼓励不变性。因此,例如,任何删除都可以只是一个过滤器。
这里有几件事情需要考虑。鉴于此代码:
messages.splice(messages.indexOf('hello'), 1);
messages = messages;
Run Code Online (Sandbox Code Playgroud)
这里发生的事情是:
"hello"这里的假设是"hello" 需要存在,否则可能会从数组中删除最后一项(因为indexOf返回-1)。
因此原始数组是变异的:取决于上下文,有时比将整个数组复制到新数组更可取;否则,避免这种突变通常是更好的做法。
所以。如果你想完全拥有这种行为,这可能是你能拥有的最好的代码。例如,以过滤器为例:
messages = messages.filter(message => message !== "hello")
Run Code Online (Sandbox Code Playgroud)
这里发生的事情是:
"hello"所以它和原来的代码有很大的不同:首先,它总是循环整个数组。如果您有数千个元素,即使您"hello"在第二个索引处只有一个,它也会始终迭代所有元素。也许这是你想要的,也许不是。如果元素是唯一的,比如一个 id,也许你想一旦找到它就停下来。其次,它返回一个新数组。同样,这通常比改变数组更好,但在某些情况下,最好改变它而不是创建一个新数组。
所以,如果你想改变原始数组,最好坚持你的原始代码。
相反,如果您不在乎(例如 的示例push),我相信在 svelte 开发人员的意图中,您的代码将大致翻译为:
let i = messages.indexOf("hello");
messages = [...messages.slice(0, i), ...messages.slice(i + 1)];
Run Code Online (Sandbox Code Playgroud)
(仍然假设有一条"hello"消息并且您只对第一次出现感兴趣)。
遗憾的是 JS 没有更好的语法来处理切片。