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