javascript const 真的是不变的吗?在还原?
Posted
技术标签:
【中文标题】javascript const 真的是不变的吗?在还原?【英文标题】:are javascript const really constant? in redux? 【发布时间】:2019-12-27 20:40:58 【问题描述】:我的商店里有这个 reducer,初始状态 initialProcessingState
是从另一个源文件导入的。
import
ACTN_IS_PROCESSING
from '../config/action-types.js';
import initialProcessingState from "./redProcessing-initial.js";
export default function (state = initialProcessingState, action)
switch (action.type)
case ACTN_IS_PROCESSING:
return
...state,
...action.isProcessing
default:
return state;
源文件中的定义如下:
export const initialProcessingState =
keys: [],
mostRecentStatus: false,
neverStale: true
现在我的商店通过订阅将状态保存到本地存储中
store.subscribe(() =>
updateLocalStorage(store);
)
像这样……
import initialProcessingState from "../reducers/redProcessing-initial.js";
var updateLocalStorage = debounce((store) =>
const state = store.getState();
var _state =
...state,
isProcessing: ...initialProcessingState
;
localStorage.setItem('reduxState', JSON.stringify(_state))
, 100);
我的意图是用它的初始状态覆盖isProcessing
,在initialProcessingState
中定义为const
。
很遗憾不起作用。因为每次调用updateLocalStorage
,initialProcessingState
的值不是初始值,而是后续reducer 调用的当前更新状态。
这怎么可能?这是const
。
我的临时解决办法是涉及JSON.parse(JSON.stringify(initialProcessingState))
:
const _initialProcessingState = JSON.parse(JSON.stringify(initialProcessingState));
var updateLocalStorage = debounce((store) =>
const state = store.getState();
//this is not the best way
console.log("updateLocalStorage", "initialProcessingState", initialProcessingState, _initialProcessingState);
var _state =
...state,
isProcessing: ..._initialProcessingState
;
localStorage.setItem('reduxState', JSON.stringify(_state))
, 100);
以下还不足以使其正常工作:
const _initialProcessingState = initialProcessingState;
有人可以帮忙吗?
【问题讨论】:
javascript 常量与其他语言不同。常量不是一成不变的。如果你的常量是指一个对象或数组,这个对象可以改变,你不能重新分配常量。 澄清这一点:const
的不变之处是对对象/值的引用。这是无法改变的。对象本身及其属性可以被改变。想想const biologicalFather = ...;
这是不变的,永远不会改变。 biologicalFather.facialHair
不是恒定的。并且所有更改都将适用于/对所有引用他的人可见。
【参考方案1】:
const 声明创建一个对值的只读引用。它 并不意味着它持有的值是不可变的,只是变量 无法重新分配标识符。例如,在 content 是一个对象,这意味着对象的内容(例如,它的 属性)可以更改。
来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const
编辑
@Apolo 在他的评论中指出,提及 Object.freeze()
可能很重要。
对象
Object.freeze() 方法冻结一个对象。冻结的物体不能 不再改变;冻结对象可防止新属性 被添加到它,现有的属性被删除,防止 改变可枚举性、可配置性或可写性 现有属性,并阻止现有属性的值 从被改变。此外,冻结一个物体也可以防止它 原型不会被改变。
但是对于Object.freeze()
,同样重要的是要注意它没有扩展到冻结的object持有的值:
请注意,作为对象的 [对象] 值仍然可以修改,除非它们 也被冻结了。
数组
作为一个对象,数组可以被冻结;这样做之后,它的元素 不能更改,也不能添加或删除任何元素 数组。
EDIT部分中的来源:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze
【讨论】:
为那些正在寻找创建不可变对象的方法的人添加一个关于Object.freeze
的词会很高兴 (developer.mozilla.org/fr/docs/Web/JavaScript/Reference/…)【参考方案2】:
initialProcessingState
的值是对对象的引用。该值不能改变。
它引用的对象可以被变异。
【讨论】:
【参考方案3】:const
表示无法重新分配引用。这就是为什么在分配字符串或数字的情况下,它们保持不可变,但在分配对象和数组时,可以通过它们的引用来修改其内容,使它们不是不可变的。
【讨论】:
【参考方案4】:来自MDN:
const 声明创建一个对值的只读引用。它 并不意味着它持有的值是不可变的,只是变量 无法重新分配标识符。例如,在 content 是一个对象,这意味着对象的内容(例如,它的 属性)可以更改。
const foo = bar : 'baz' ;
foo.bar = 'foo'; // works, because it doesn't change what foo is.
foo = null; // will fail, since it tries to change what foo is
您可以查看Object.freeze,但这只会冻结第一级:
const foo = Object.freeze(
bar : 'baz',
baz : foo : 'bar'
);
foo.bar = 'foo'; // will not change since foo is frozen
foo.baz.foo = 'foo'; // will change, since foo.baz is not frozen
console.dir(foo)
【讨论】:
以上是关于javascript const 真的是不变的吗?在还原?的主要内容,如果未能解决你的问题,请参考以下文章
javascript真的是异步的吗?且看setTimeout的实现原理以及setTimeout的使用场景