奇怪的javascript toString()行为

奇怪的javascript toString()行为,javascript,reactjs,use-reducer,Javascript,Reactjs,Use Reducer,我试图使用toString将一个类临时输出到DOM。 我得到了一些行为,我不明白被重写的toString()总是在哪里输出初始状态。但是,如果使用了外部函数(即stateToString)或甚至JSON.stringify,更新后的状态会像我预期的那样输出 下面是我试图尽量少地再现这种行为。 重申一下,我的预期行为是让所有人最初都输出:[“initial”],他们就是这样做的。但是,单击按钮时,toString()输出不会更新,但其他两个会更新 这似乎特别奇怪,因为stateToString和S

我试图使用toString将一个类临时输出到DOM。 我得到了一些行为,我不明白被重写的
toString()
总是在哪里输出初始状态。但是,如果使用了外部函数(即stateToString)或甚至
JSON.stringify
,更新后的状态会像我预期的那样输出

下面是我试图尽量少地再现这种行为。 重申一下,我的预期行为是让所有人最初都输出:
[“initial”]
,他们就是这样做的。但是,单击按钮时,
toString()
输出不会更新,但其他两个会更新

这似乎特别奇怪,因为
stateToString
State。toString
似乎本质上是相同的函数,只是一个函数将State作为接收器,另一个函数将State作为参数

如果有人能解释为什么会发生这种行为,我将不胜感激

import React, { useReducer } from 'react';

class State { 
  constructor(xs) { this.xs = xs } 
  toString = () => `[${this.xs}]`
}

const stateToString = state => `[${state.xs}]`;

const reducer = (state, action) => ({
  ...state,
  xs: [...state.xs, action.x]
});

const App = () => {
  const [state, dispatch] = useReducer(reducer, new State(["initial"]));
  return (
    <div>
      <button onClick={() => dispatch({ x: Math.random() })}>click</button><br />
      toString:  {state.toString()}<br />
      print:     {stateToString(state)}<br />
      stringify: {JSON.stringify(state)}
    </div>
  );
};

export default App;
import React,{useReducer}来自“React”;
类状态{
构造函数(xs){this.xs=xs}
toString=()=>`[${this.xs}]`
}
const stateToString=state=>`[${state.xs}]`;
const reducer=(状态、操作)=>({
……国家,
xs:[…state.xs,action.x]
});
常量应用=()=>{
const[state,dispatch]=useReducer(reducer,newstate([“initial”]);
返回(
分派({x:Math.random()})>单击
toString:{state.toString()}
打印:{stateToString(state)}
stringify:{JSON.stringify(state)} ); }; 导出默认应用程序;
在状态上使用的
toString
方法绑定到状态的原始实例:

class State { 
  constructor(xs) { this.xs = xs } 
  toString = () => `[${this.xs}]` // Class field arrow function
}
这里的class字段意味着无论调用
toString
的调用上下文是什么,它都将返回初始状态的
this.xs
。即使reducer更新了状态,状态的构造函数也不会再次运行

在以后调用
App
时,会创建初始状态,然后执行一些操作对其进行更新,从而使
state
变量成为更新的对象,但它仍然有一个绑定到初始状态的
toString
方法

下面是vanilla JS中的行为示例:

const obj={
瓦尔:‘瓦尔’,
toString:()=>obj.val
};
const copiedObj={…obj,val:'newVal'};
log(copiedObj.toString())