JSON.stringify(value)
会将JavaScript值转换为JSON字符串。 JSON.parse(value)
会将有效的JSON字符串转换为JavaScript值(对象,数组或其他JSON可用的原语)。
为什么要采用JavaScript值并将其通过JSON移动?均值取一个值,然后将其字符串化,然后再解析回去。据我了解,这毫无用处,只是浪费机器资源。
我问这是因为我遇到过此功能:
function ser(value) {
return value == null ? null : JSON.parse(JSON.stringify(value))
}
可以在Marijn Heverbeke的Eloquent JavaScript书的第11章的crow-tech.js中的sandbox中找到它,我想知道他为什么要这么做!
答案 0 :(得分:4)
这是一种便宜的方法to deep clone an object in JavaScript。请考虑以下内容:
function a() {
const obj = {name: "fred"};
b(obj);
console.log(obj);
}
function b(obj) {
obj.age = 42;
}
a();
函数a
会在修改对象时将对象传递给b
。有时,这就是您想要的,而其他时候,您希望保留原始对象以防修改,因此您必须对其进行克隆。 JavaScript没有任何功能,但是JSON.stringify
-> JSON.parse
将为您创建一个新对象,以便将其用于克隆:
function a() {
const obj = {name: "fred"};
b(JSON.parse(JSON.stringify(obj)));
console.log(obj);
}
function b(obj) {
obj.age = 42;
}
a();
这很好地说明了 可能会出错,但是在现实世界中,这并不总是那么简单。上面的操作也可以通过对象的 shallow 克隆
来完成
function a(){
const obj = {name: "fred"};
b(Object.assign({}, obj)); //shallow clone
console.log(obj);
}
function b(obj) {
obj.age = 42;
}
a();
但是,在以下情况下这将失败:
const obj = {
name: "fred",
child: { name: "pebbles" }
};
const objClone = Object.assign({}, obj)
objClone.age = 42;
objClone.child.age = 2;
console.log('the "cloned" object was modified', objClone);
console.log("so was the original nested object", obj);
这是因为嵌套对象child
不是 克隆的,所以我们修改了父级的顶级克隆,但又修改了原始的子级。这是深度克隆的有用时机:
const obj = {
name: "fred",
child: { name: "pebbles" }
};
const objClone = JSON.parse(JSON.stringify(obj));
objClone.age = 42;
objClone.child.age = 2;
console.log('the cloned object was modified', objClone);
console.log("none of the original was", obj);
这不能解决所有问题。 JSON.stringify
然后JSON.parse
仅适用于任何地方的非常简单的对象,它不会复制原型或函数。一些例子:
const obj = { name: "Alice" };
const proto = { age: 42 };
Object.setPrototypeOf(obj, proto);
console.log("assembled object", obj);
const clone = JSON.parse(JSON.stringify(obj));
console.log("cloned object", clone);
const objWithFunction = { name: "Bob", getAge: function() { return 42; } };
console.log("object with function assigned to property", objWithFunction);
console.log("getAge from original", objWithFunction.getAge());
const cloneWithFunction = JSON.parse(JSON.stringify(objWithFunction));
console.log("cloned object with function assigned to property", cloneWithFunction);
console.log("getAge from clone", cloneWithFunction.getAge());
function Person(name, age) {
this.name = name;
this.age = age;
}
const p = new Person("Carol", 42);
console.log("what is p:", p);
console.log("is p a Person?", p instanceof Person);
const clone = JSON.parse(JSON.stringify(p));
console.log("what is clone:", clone);
console.log("is clone a Person?", clone instanceof Person);
console.log("the clone is actually a plain object:", Object.getPrototypeOf(clone) == Object.prototype);
答案 1 :(得分:2)
JSON.parse(JSON.stringify(value))
这主要用于克隆对象。您不能直接将对象复制到另一个变量,因为对象是通过引用复制的。
let user = {name : "John"}
let newUser = user; // newUser and user refer to same object (ie same memory location.) .
如果您修改user
,那么newUser
也将被修改。这是因为对象是通过引用而不是按值复制的。
因此,使用您指定的方法进行对象复制。
示例
let value = {"name": "John"}; // this is a object.
JSON.stringify(value) // were are changing the type object to string
可以按值复制字符串。
现在我们需要再次将字符串转换为Object,因为我们使用
let newValue = JSON.parse(JSON.stringify(value));
这将返回一个对象-value
的克隆
现在值和newValue是两个不同的对象。