在一个回购中,我看到了一条线。
var foo = JSON.parse(JSON.stringify(foo));
我认为这是试图剥离对象的任何方法。我无法真正看到它做任何其他事情。是否有更有效的方法来尝试这个?节点是否优化了这个?
答案 0 :(得分:6)
在您现在公开的code context中,此技术用于制作传递给函数的对象的副本,以便对该对象的修改不会修改原始对象。这是您链接的上下文:
// route reply/error
this.connection.on('message', function(msg) {
var msg = JSON.parse(JSON.stringify(msg));
var handler;
if (msg.type == constants.messageType.methodReturn || msg.type == constants.messageType.error) {
handler = self.cookies[msg.replySerial];
if (msg.type == constants.messageType.methodReturn && msg.body)
msg.body.unshift(null); // first argument - no errors, null
if (handler) {
delete self.cookies[msg.replySerial];
var props = {
connection: self.connection,
bus: self,
message: msg,
signature: msg.signature
};
if (msg.type == constants.messageType.methodReturn)
handler.apply(props, msg.body); // body as array of arguments
else
handler.call(props, msg.body); // body as first argument
}
注意:此剪辑中包含msg.body.unshift(null)
的行。如果没有制作副本,那将修改原始对象。
另请注意,重新声明var msg
实际上并未定义新变量。由于msg
已在此范围内定义为函数参数,因此var msg
不会重新声明它(从技术上讲,这在代码中使用var
是错误的。)
使用此类代码的常见原因是克隆对象(制作对象的深层副本,其中包括嵌入对象和数组的所有属性都将被复制)。
var obj = {
list: [1,2,3],
items: [{language: "English", greeting: "hello"},
{language: "Spanish", greeting: "hola"},
{language: "French", greeting: "bonjour"}]
}
// make a completely independent copy of obj
var copy = JSON.parse(JSON.stringify(obj));
copy.items[0].greeting = "Yo";
console.log(obj.items[0].greeting); // "hello"
console.log(copy.items[0].greeting); // "Yo"
注意:这仅作为完整副本,其对象是普通的对象类型,并且没有作为函数的自定义属性。并且,因为JSON.stringify()
不支持循环引用或自引用,所以您不能拥有这些引用或自引用。并且,如果您对同一对象有多个引用,则每个引用都将复制到一个新的单独对象。并且,JSON.stringify()
和JSON.parse()
的组合不支持除Object
,RegExp
之类的普通Date
之外的对象或任何您自己的对象自定义对象(将它们转换为普通对象)。因此,这个程序有一些局限性,但它对大多数情况都很简单。
Per Matt(在评论中),可以看到一个自定义函数,用于创建支持循环引用的对象的克隆,并支持某些类型的自定义对象{。{3}}。
如果有人读到这个并没有意识到,将对象分配给另一个变量不能在Javascript中复制。 Javascript中的赋值就像设置指向同一对象的指针一样。然后每个变量指向相同的底层对象,因此通过任一变量修改对象最终会在这两种情况下修改同一个对象,如下所示:
var obj = {
list: [1,2,3],
items: [{language: "English", greeting: "hello"},
{language: "Spanish", greeting: "hola"},
{language: "French", greeting: "bonjour"}]
}
var copy = obj;
// modify copy
copy.items[0].greeting = "Yo";
// both obj and copy refer to the exact same object
console.log(obj.items[0].greeting); // "Yo"
console.log(copy.items[0].greeting); // "Yo"
因此,偶尔需要制作对象的实际深层副本。
答案 1 :(得分:-1)
如果从原型中删除方法是您想要的,请考虑创建一个新对象并传输所有旧对象的属性。
如果剥离属性是您想要的,则遍历该对象并检查该属性是否为函数:
for(key in ob)
{
if(typeof ob[key] === 'function')
{
delete ob[key];
}
}
或许你希望完成的是两者的结合。