剥离javascript对象的方法

时间:2015-03-20 01:17:11

标签: javascript node.js

在一个回购中,我看到了一条线。

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

我认为这是试图剥离对象的任何方法。我无法真正看到它做任何其他事情。是否有更有效的方法来尝试这个?节点是否优化了这个?

2 个答案:

答案 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()的组合不支持除ObjectRegExp之类的普通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];
    }
}

或许你希望完成的是两者的结合。

相关问题