通过JSON移动数据的目的

时间:2018-11-02 04:34:23

标签: javascript json

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中找到它,我想知道他为什么要这么做!

2 个答案:

答案 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是两个不同的对象。