剥离JavaScript对象的方法
在一个回购中,我看到一条线。
var foo = JSON.parse(JSON.stringify(foo));
我认为这是试图剥离任何方法的对象。 我真的不能看到它做任何事情。 有没有更有效的方法来尝试这个? 节点是否优化了这个?
在你现在已经公开的代码上下文中 ,这个技术被用来创build一个传递给一个函数的对象的副本,以便对该对象的修改不会修改原始的。 以下是您的链接的上下文:
// 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
实际上并没有定义一个新的variables。 由于msg
已经在此作用域中定义为函数参数,因此它不会被var msg
重新声明(这在技术上是代码中使用var
的错误)。
使用这种types的代码的通常原因是克隆一个对象(复制包含embedded对象和数组的所有属性的对象的深层副本)。
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"
注意:这只能作为一个普通的对象types的对象的完整副本,并没有自定义的属性是函数。 而且,由于JSON.stringify()
不支持循环引用或自引用,因此不能使用这些引用。 而且,如果您有多个对同一对象的引用,则每个引用将被复制到一个新的独立对象。 而且, JSON.stringify()
和JSON.parse()
的组合不支持除普通Object
例如RegExp
, Date
或任何自定义对象(它们将它们转换为普通对象)以外的对象)。 所以,这个程序有一些限制,但是对于大多数情况来说,这个限制很简单。
每马特(在注释),一个自定义函数创build一个支持循环引用的对象的克隆,并支持某些types的自定义对象可以在这里看到。
如果读者没有意识到,将对象赋值给另一个variables不会在Javascript中进行复制。 在Javascript中的赋值就像设置一个指向同一对象的指针一样。 然后每个variables都指向相同的底层对象,所以通过这两个variables修改对象最终会修改同一个对象,如下所示:
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"
因此,偶尔需要做一个对象的实际深层拷贝。
如果从原型中删除方法是您想要的,请考虑创build一个新对象并转移所有旧对象的属性。
如果剥离属性是一个函数是你想要的,遍历对象并检查属性是否是一个函数:
for(key in ob) { if(typeof ob[key] === 'function') { delete ob[key]; } }
或者,你希望完成的是两者的结合。