将成员函数和变量从一个对象复制到另一个对象时,在存储器方面会发生什么

时间:2019-02-14 23:20:46

标签: javascript

让我们说我们有两个对象和一个如下使用函数:

function using(namespace, scope){
    for(x in namespace){
        scope[x] = namespace[x];
    }
}

function fooClass(){
    this.foo = function(){
        console.log("foo");
    }

    this.bar = function(){
        console.log("bar");
    }
}

var myFoo = new fooClass();

function barClass(){
    using(myFoo, this);
}

var myBar = new barClass();
myBar.foo();

在此示例中,它继承了从fooClass到barClass的所有内容。这是我正在尝试进行的各种大规模情况的一个小例子。我在实际用例中使用的namespace很大。我知道javscript通过所有对象的引用传递。 namespace中的某些项目是对象数组或包含对象数组或仅是函数的单个对象。大多数原始变量都是私有变量,因此不应保留。

我很好奇我要复制多少数据,并参考多少数据?应该引用存储在namespace中的对象,但是函数呢?它们像原始变量一样被复制还是被引用?更重要的是,我应该担心使用此using()函数的内存消耗吗?

我写这本书的主要原因是因为有时我不得不调用一个深层嵌套的对象,这使代码更具可读性,但是如果我要牺牲内存的话,我不想这样做。

1 个答案:

答案 0 :(得分:1)

使用namespacespace属性复制到for ... in时,所有原始和对象引用值都是重复的,因此它们占用的内存是原来的两倍。

JavaScript对象值(包括函数对象)保存在变量中,作为对保存对象属性的内存中“某处”的引用。复制操作仅复制引用,而不复制基础属性名称和值或功能代码,因此创建副本所消耗的额外内存类似于复制原始值。

但是对于所示的用例,您可能希望扩展基础myFoo对象,以便它由barClass实例继承。当然,这确实意味着不会拍摄mFoo的快照,并且myBar实例将继承对myFoo的任何将来的更改。

ES5示例:

let myFoo = {foo: "foo"};

function myBar() {
    this.bar = "bar";
}
myBar.prototype = Object.create( myFoo);
myBar.constructor = myBar;

let bar = new myBar();
console.log( bar.foo);

ES2015需要做更多的工作才能创建中间函数来扩展对象不是函数

let myFoo = {foo: "foo"};
function interFoo() {
};
interFoo.prototype = myFoo;
   
class myBar extends interFoo {
   constructor() {
      super();
      this.bar = "bar";
   }
}

let bar = new myBar();
console.log( bar.foo);

请注意,如果直接扩展fooClassmyFoo的构造函数),则创建barClass的实例将通过调用forClass作为超类构造函数在本地重新创建所有属性。 -可能不是您想要的。