JSON.stringify(intArray)和直接发intArray有什么不同?
这是一个很好的问题!让我详细解释 JSON.stringify(intArray) 和直接发送 intArray 的区别:
核心区别
1. 直接发送 intArray
worker.postMessage(intArray); // 直接发送数组对象
2. 使用 JSON.stringify(intArray)
worker.postMessage(JSON.stringify(intArray)); // 发送JSON字符串
在Web Worker中的实际效果
1、直接发送数组(两种写法效果相同)
// script.js中
worker.postMessage(intArray);
// 或
worker.postMessage([45, 67, 23, 89]);
// worker.js中接收
onmessage = function(event) {
console.log(typeof event.data); // "object"
console.log(Array.isArray(event.data)); // true
console.log(event.data[0]); // 45(可以直接使用)
}2、发送JSON字符串
// script.js中
worker.postMessage(JSON.stringify(intArray));
// 实际发送的是 "[45,67,23,89]"
// worker.js中接收
onmessage = function(event) {
console.log(typeof event.data); // "string"
console.log(Array.isArray(event.data)); // false
console.log(event.data[0]); // "["(字符串的第一个字符)
// 必须解析才能使用
var intArray = JSON.parse(event.data);
console.log(intArray[0]); // 45
}Web Worker的通信机制
1、结构化克隆算法 (Structured Clone Algorithm)
Web Worker通信时,数据是通过复制而不是引用传递的。当调用 postMessage() 时:
// 原始数据 let originalArray = [45, 67, 23, 89]; // 发送数据 worker.postMessage(originalArray); // 在Worker中接收的是一个全新的副本 // 修改副本不会影响原始数组
2、支持的数据类型
结构化克隆算法支持:
✅ 基本类型(number, string, boolean, null, undefined)
✅ 数组和对象
✅ Date
✅ RegExp
✅ Blob
✅ File
✅ ImageData
✅ 等等
为什么有时候用JSON.stringify?
1. 明确的数据序列化
// 用JSON.stringify显得多余,但明确表达了意图 worker.postMessage(JSON.stringify(intArray)); // 强调:我要把数据转换成字符串格式传递
2. 兼容非常老旧的浏览器
某些非常老旧的浏览器对结构化克隆支持不完善,JSON字符串更安全。
3. 自定义序列化逻辑
// 可以添加额外的处理
worker.postMessage(JSON.stringify({
data: intArray,
timestamp: Date.now(),
type: "randomNumbers"
}));4. 调试方便
// 发送前可以打印查看 console.log(JSON.stringify(intArray)); // 可以看到完整的字符串形式 worker.postMessage(JSON.stringify(intArray));
性能对比
// 大数组测试 (100万个数字)
let bigArray = new Array(1000000).fill(1);
console.time("直接发送");
worker.postMessage(bigArray); // 结构化克隆
console.timeEnd("直接发送"); // 较快
console.time("JSON发送");
worker.postMessage(JSON.stringify(bigArray)); // 先转换字符串
console.timeEnd("JSON发送"); // 较慢(序列化+传输)实际应用场景
场景1:直接发送数组(推荐)
// script.js
worker.postMessage(intArray);
// worker.js
onmessage = function(e) {
let data = e.data; // 直接是数组,可直接使用
data.forEach(item => console.log(item));
}场景2:发送JSON字符串(特殊需求)
// script.js
worker.postMessage(JSON.stringify({
numbers: intArray,
config: {
filter: 5,
colorize: true
}
}));
// worker.js
onmessage = function(e) {
let packet = JSON.parse(e.data);
let numbers = packet.numbers;
let config = packet.config;
// 处理数据...
}结论
在这个特定的代码示例中,使用 JSON.stringify 是多余的,因为:
Web Worker的postMessage已经能很好地处理数组
添加了不必要的序列化和解析步骤
增加了代码复杂度
可能的原因:
开发者习惯使然
为了兼容性考虑
代码是从其他地方复制来的
现代Web开发中,直接发送数组即可,不需要手动JSON序列化。