javascript - 获取/设置状态对象(vanilla js)

标签 javascript state

我尝试过寻找重复项,但总是得到 React 答案(可以理解)。

只是想知道这是否以某种方式获取和设置状态对象,以防止由于引用/改变原始状态对象而产生意外的“气味”。

抱歉,如果这看起来很简单,但我只是不确定。对更好/最佳实践非常感兴趣(如果它没有被归类为太宽泛的话)。

let state = {
  name: 'Nick',
  sex: 'male',
  hobbies: []
}

const updateHobbies = async() => {
  const hobbies = // some fetch call
   
  setState('hobbies', hobbies);
}

const setState = (key, value) => {
  state = { ...state, 'key': value }
}
const getState = () => {
  return { ...state }
}

最佳答案

正如所指出的,使用经过尝试和测试的库当然是一个好主意。但有时自己动手并不是一个坏主意,特别是出于学习目的等。

下面我创建了一个带有基本深拷贝的小片段。

您会注意到浅拷贝 {...} 版本会更改 a,但 deepCopy 不会。

如果 ES 规范实现了深层复制,那就太好了,有时人们只是这样做 -> JSON.parse(JSON.stringify(data)) 这不太好,因为它会丢失大量数据类型当然,克隆对象并不简单,因为需要特别注意对象类型,例如。我的代码片段必须专门处理日期,其他对象可能也需要特别注意。但也许这可以使用与 Symbol.iterator 完成迭代相同的技术来完成..

const CloneSymbol = Symbol('clone');

Date.prototype[CloneSymbol] = 
  d => new Date(d.getTime());
  
//custom Person object with clone.  
class Person {
  constructor (first, last) {
    this.first = first;
    this.last = last;
  }
  get full() { return `${this.first} ${this.last}` }
}
Person.prototype[CloneSymbol] = s => {
  return new Person(s.first, s.last);
}
  
  

const deepCopy = obj => {
  const m = Object.entries(obj).map(
    ([k, v]) => {
       if (v === null) return [k, v];
       if (typeof v === 'object') {           
         const fn = v.constructor
           .prototype[CloneSymbol];
         return [k, fn ? fn(v) : deepCopy(v)]
       } else return [k, v];
    }
  );
  return Array.isArray(obj) 
    ? m.reduce((a, [i, v]) => {
      a[i] = v;
      return a;
    }, [])
    : Object.fromEntries(m);
}


const a = {
  nullVal: null,
  seven: 7,
  person: new Person('bill', 'clinton'),
  date: new Date(),
  one: 'one',
  arr: ['hello', 'there', [1,2,3]]
}

//deep copy, b has no mutation
//a is not effect..
const b = deepCopy(a);
b.arr[0] = 'bye';
b.date.setDate(1);
b.arr[2].push(4);
console.log(b.person.full);


//shalow copy, look at a & c
const c = {...a}; 
c.arr[1] = 'oops';

console.log(a);
console.log(b);
console.log(c);
console.log(a.person === b.person);

关于javascript - 获取/设置状态对象(vanilla js),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74194066/

相关文章:

php - Jquery Uploadify 图像多个实例并调用每个实例完成前一个实例

javascript - 如何从选择标签上的事件中检索对象?

javascript - 单击事件之前未定义 Prop

java - 状态转换表如何工作?

list - 如何将我的数据保存在列表中,以便在Flutter应用程序的整个生命周期中都可以使用?

javascript - 是否可以使用 WebRTC 连接到特定主机?

javascript - 使用逻辑 OR 运算符的 if 语句中的多重比较在 JavaScript 中不起作用

php - 故意减慢 HTML/PHP 页面加载以进行测试

haskell - 在无状态世界中保持状态

使用 Haskell/Megaparsec : StateT for building up local, 词法范围进行解析?