[英]Stringify object differently depending on context
我有一个带有toJSON方法的对象:
const v = {
foo: 'zoom1',
bar: 'zoom2',
toJSON(){
return {foo: this.foo}
}
}
当我调用JSON.stringify(v)
我会得到{foo:'zoom1'}
-我的问题是-有没有一种方法可以根据谁调用JSON.stringify()来对其进行不同的字符串化,例如,如果我想要:
{bar: 'zoom2'}
代替? dunno,也许有一个不错的设计模式。
实际上,您可以使用stringify函数的replacer 参数 :
更改字符串化过程的行为的函数,或用作白名单的String和Number对象数组,用于选择/过滤要包含在JSON字符串中的值对象的属性。 如果此值为null或未提供,则对象的所有属性都将包含在结果JSON字符串中。
例:
const v = {
foo: 'zoom1',
bar: 'zoom2'
};
JSON.stringify(v, ['foo']);
// Outputs "{"foo":"zoom1"}
JSON.stringify(v, ['bar']);
// Outputs "{"bar":"zoom2"}
JSON.stringify(v, ['foo', 'bar']);
// Outputs "{"foo":"zoom1", "bar":"zoom2"}
有两个不推荐使用的方法,使您可以确定谁调用了特定函数: arguments.callee和function.caller 。
但是,我建议您不要定义尝试序列化的对象或猴子修补内置序列化功能,而应该定义帮助程序序列化方法,这些方法将以不同的方式返回对象(例如对同一数据的不同视图) )
类似于以下想法,如果要返回对象的两个不同视图是flat
和deep
:
const myData = {}
const flatSerializer = (data) => {}
const deepSerializer = (data) => {}
const flatString = flatSerializer(myData)
const deepString = deepSerializer(myData)
如果要引入一些函数组合,还可以创建不同的方式来表示传递到同一序列化函数中的数据。
使用相同的示例,您可能会遇到类似以下情况:
const myData = {}
const serializer = fn => data => fn(data)
const flat = data => {}
const deep = data => {}
const flatSerialize = serializer(flat)
const deepSerialize = serializer(deep)
const flatString = flatSerialize(myData)
const deepString = deepSerialize(myData)
一种选择是使用replacer
参数进行stringify
。 它是一个函数,在对象中将每个属性的键和值进行字符串化,如果您从中返回undefined
,则该属性将从字符串化结果中排除。
您可能在库中有一堆替换器函数,对于要排除的一组属性,每个替换器函数均返回未定义的值,因此本质上是创建对象的不同“视图”。 然后,调用者在调用stringify时选择所需的替换者。
还没有尝试过,但是我认为答案是自定义替换器,如下所示:
const result = JSON.stringify(v, (val) => {
if(val instanceof whatever){
return {bar: val.bar};
}
return val;
});
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.