Svelte响应式疑问:为何obj.foo.bar显示bazz且控制台输出异常
Svelte响应式疑问解答
先贴出你的代码:
<script> let numbers = [1, 2, 3, 4]; let obj = { foo:{ bar: "bar" } } function addNumber() { numbers.push(numbers.length + 1); numbers = numbers; } const changeToBaz = (tempObj) => { tempObj.foo.bar = 'bazz'; } $: sum = numbers.reduce((t, n) => t + n, 0); $:{ console.log('sum: ', sum); console.log('obj: ', obj); changeToBaz(obj); } </script> <p>{numbers.join(' + ')} = {sum}</p> <p>{obj.foo.bar}</p> <button on:click={addNumber}> Add a number </button>
问题1:页面上obj.foo.bar显示为bazz的原因
- Svelte对对象、数组这类引用类型的响应式追踪,不止看变量是否重新赋值,还会追踪内部属性/元素的修改——只要模板里用到了这个对象的属性(比如你模板里渲染了
obj.foo.bar),Svelte就能检测到属性变化并更新DOM,不需要手动写obj = obj触发更新。 - 你的响应式代码块
$:{ ... }会在组件初始化时自动执行,初始化阶段就调用了changeToBaz(obj)把obj.foo.bar改成了bazz,所以页面一开始就显示修改后的值。
问题2:控制台在调用changeToBaz前输出的obj已是bazz的原因
这是浏览器控制台的特性:打印对象时显示的是实时引用,不是打印那一刻的快照。
代码执行顺序确实是先console.log(obj)再调用changeToBaz修改属性,但控制台里的对象会实时更新为最新状态。如果想看到打印那一刻的真实值,可以把对象转成字符串打印:
console.log('obj: ', JSON.stringify(obj));
内容的提问来源于stack exchange,提问作者Arix
相关产品推荐
相关产品推荐

