假设我们有两个对象和一个像这样的 using 函数:
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 的所有内容。这是我正在考虑这样做的各种大规模情况的一个小例子。我在实际用例中使用的命名空间相当大。我知道 javscript 通过引用传递所有对象。命名空间中的某些项目是对象数组或包含对象数组或仅包含函数的单个对象。大多数原始变量都是私有(private)的,因此它们不应该保留。
我很好奇我复制了多少数据以及引用了多少数据?存储在命名空间
中的对象应该被引用,但是函数呢?它们是像原始变量一样被复制还是被引用?更重要的是,我应该担心这个 using()
函数的内存消耗吗?
我写它的主要原因是因为有时我必须调用深度嵌套的对象,这使得代码更具可读性,但如果我牺牲内存,我不想这样做。
最佳答案
使用for ... in
将namespace
属性复制到space
时,所有基元和对象引用值都会重复,因此它们会占用两倍的空间尽可能多的内存。
JavaScript 对象值(包括函数对象)保存在变量中,作为对内存中保存对象属性的“某处”的引用。复制操作仅复制引用,而不复制基础属性名称和值或函数代码,因此创建副本消耗的额外内存与复制原始值类似。
对于所呈现的用例,您可能希望扩展基本 myFoo
对象,以便它由 barClass
实例继承。当然,这确实意味着不会拍摄 mFoo
的快照,并且 myBar
实例将继承对 myFoo
的任何 future 更改。
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);
请注意,如果直接扩展 fooClass
(myFoo
的构造函数),则创建 barClass
实例将通过调用 forClass
作为父类(super class)构造函数 - 这可能不是您想要的。
关于javascript - 将成员函数和变量从一个对象复制到另一个对象时,内存方面会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54700592/