javascript - 从 javascript 对象中剥离方法

标签 javascript node.js

在一个 repo 协议(protocol)中,我看到了一行。

var foo = JSON.parse(JSON.stringify(foo));

我认为这是试图从对象中剥离任何方法。我真的看不到它在做任何其他事情。有没有更有效的方法来尝试这个? Node 是否对此进行了优化?

最佳答案

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 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 以外的对象,例如 RegExpDate 或您自己的任何自定义对象(它们将它们变成普通对象)。因此,此过程存在一些局限性,但对于大多数情况而言,它的工作原理非常简单。


Per Matt(在评论中),可以看到创建支持循环引用并支持某些类型的自定义对象的对象克隆的自定义函数 here .


如果阅读本文的人没有意识到,将一个对象分配给另一个变量并不会在 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"

因此,偶尔需要对对象进行实际的深拷贝。

关于javascript - 从 javascript 对象中剥离方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29157830/

相关文章:

php - 带有 mysql 池的 node.js(集群)的基准测试性能 : Lighttpd + PHP?

javascript - Sequelize 多对多添加功能不起作用

javascript - 从 Sequelize 中的另一个表中计数

javascript - 幻灯片之间的 jQuery/CSS 转换问题会扰乱位置 :fixed performance inside slide

javascript - 使用 z-index 堆叠 XHTML 元素

javascript - 在javascript中打印/警告数组

javascript - 如何使用nodejs获取uber api访问 token

Node.js 安装 - CentOS 6.9

javascript - 如何在 Shadow DOM 中不渲染 <content> 标签中的内容?

javascript - 如何在谷歌浏览器中禁用网络存储?