Node.js - 如何 write/serialize 包含函数和特殊值的任意 JavaScript 对象并将其保存到 .js 文件
Node.js - How to write/serialize an arbitrary JavaScript object that contains functions and special values and save it to a .js file
我有一个 JavaScript 对象,其中包含 Infinity
等函数和特殊值,以及字符串和数字:
const myObject = {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
我想将它保存到一个文件中,这样生成的内容如下所示:
export default function () {
return {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
}
我曾尝试使用 JSON.stringify()
,但这不适用于函数和特殊值,因为它们无效 JSON:
writeFileSync('my-output.js', `
export default function () {
return ${ JSON.stringify(myObject) };
}
`);
const myObject = {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
console.log(JSON.stringify(myObject, null, 4));
还有其他方法吗?
除了 JSON.stringify
,您需要一种不同的方式来序列化您的对象,也许是这样的:
// Pretty:
const TAB = ' ';
const BR = '\n';
const CBR = `,${ BR }`;
// Minified:
// const TAB = '';
// const BR = '';
// const CBR = ',';
function arrayAsString(arr, depth=0) {
const _ = TAB.repeat(depth - 1);
const __ = _ + TAB;
return `[${
BR }${ arr.map(value =>
`${ __ }${ serialize(value, depth) }`).join(CBR) }${
BR }${ _ }]`;
}
function objectAsString(obj, depth=0) {
const _ = TAB.repeat(depth - 1);
const __ = _ + TAB;
return `{${
BR }${ Object.entries(obj).map(([key, value]) =>
`${ __ }${ key }: ${ serialize(value, depth) }`).join(CBR) }${
BR }${ _ }}`;
}
function serialize(value, depth=0) {
if (value === null) {
return `${ value }`;
} else if (Array.isArray(value)) {
return arrayAsString(value, depth + 1);
} else if (typeof value === 'object') {
return objectAsString(value, depth + 1);
} else if (typeof value === 'string') {
return `"${ value }"`;
} else {
return `${ value }`;
}
}
const notStringifyableObject = {
1: Infinity,
str: "my string",
num: 5,
func: () => console.log('It works! '),
mixArr: [{
value: 1
}, {
value: 2
}, 1, 2, [3, 4, 5]],
arr: [1, 2, 3],
obj: { foo: 'bar' },
nil: null,
und: undefined
};
const serialized = serialize(notStringifyableObject);
// This is what you would save in a file:
console.log(`export default ${ serialized };`);
// Check if it's actually working:
eval(`test = ${ serialized }`);
test.func();
.as-console-wrapper {
max-height: 100vh !important;
}
然后,一旦你序列化了你的对象,你可以将它的 string
表示保存到一个带有一些额外代码的文件中,以便你以后可以使用 require
加载它,就像你已经做的那样:
writeFileSync('my-output.js', `export default () => ${ serialized };`);
或:
writeFileSync('my-output.js', `export default ${ serialized };`);
请注意,这只是一个基本实现,它不支持正则表达式、日期、循环结构...因此您可能更愿意使用像 serialize-javascript
or serialize-to-js
这样的库,而不是实现您自己的解决方案。
我有一个 JavaScript 对象,其中包含 Infinity
等函数和特殊值,以及字符串和数字:
const myObject = {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
我想将它保存到一个文件中,这样生成的内容如下所示:
export default function () {
return {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
}
我曾尝试使用 JSON.stringify()
,但这不适用于函数和特殊值,因为它们无效 JSON:
writeFileSync('my-output.js', `
export default function () {
return ${ JSON.stringify(myObject) };
}
`);
const myObject = {
propertyA: "my string",
propertyB: 5,
propertyC: () => "function returing a string",
propertyD: Infinity
};
console.log(JSON.stringify(myObject, null, 4));
还有其他方法吗?
除了 JSON.stringify
,您需要一种不同的方式来序列化您的对象,也许是这样的:
// Pretty:
const TAB = ' ';
const BR = '\n';
const CBR = `,${ BR }`;
// Minified:
// const TAB = '';
// const BR = '';
// const CBR = ',';
function arrayAsString(arr, depth=0) {
const _ = TAB.repeat(depth - 1);
const __ = _ + TAB;
return `[${
BR }${ arr.map(value =>
`${ __ }${ serialize(value, depth) }`).join(CBR) }${
BR }${ _ }]`;
}
function objectAsString(obj, depth=0) {
const _ = TAB.repeat(depth - 1);
const __ = _ + TAB;
return `{${
BR }${ Object.entries(obj).map(([key, value]) =>
`${ __ }${ key }: ${ serialize(value, depth) }`).join(CBR) }${
BR }${ _ }}`;
}
function serialize(value, depth=0) {
if (value === null) {
return `${ value }`;
} else if (Array.isArray(value)) {
return arrayAsString(value, depth + 1);
} else if (typeof value === 'object') {
return objectAsString(value, depth + 1);
} else if (typeof value === 'string') {
return `"${ value }"`;
} else {
return `${ value }`;
}
}
const notStringifyableObject = {
1: Infinity,
str: "my string",
num: 5,
func: () => console.log('It works! '),
mixArr: [{
value: 1
}, {
value: 2
}, 1, 2, [3, 4, 5]],
arr: [1, 2, 3],
obj: { foo: 'bar' },
nil: null,
und: undefined
};
const serialized = serialize(notStringifyableObject);
// This is what you would save in a file:
console.log(`export default ${ serialized };`);
// Check if it's actually working:
eval(`test = ${ serialized }`);
test.func();
.as-console-wrapper {
max-height: 100vh !important;
}
然后,一旦你序列化了你的对象,你可以将它的 string
表示保存到一个带有一些额外代码的文件中,以便你以后可以使用 require
加载它,就像你已经做的那样:
writeFileSync('my-output.js', `export default () => ${ serialized };`);
或:
writeFileSync('my-output.js', `export default ${ serialized };`);
请注意,这只是一个基本实现,它不支持正则表达式、日期、循环结构...因此您可能更愿意使用像 serialize-javascript
or serialize-to-js
这样的库,而不是实现您自己的解决方案。