Javascript:实例变量和静态方法;在内存方面这没关系吗?

时间:2010-12-28 19:31:57

标签: javascript memory-management

if (typeof Object.create4 !== 'function') {
    Object.create4 = function (t) {
        var F, f, i, ins = {}, sta = {};

        for(i in t){
            // method: static, means will only exists 1, so is less memory intensive
            if(typeof t[i] === 'function'){
                sta[i] = t[i];
            }
            // vars: instance, means 1 for each object, so is more memory intensive
            else{
                ins[i] = t[i];
            }
        }

        // make a copy of the instances
        ins = jQuery.extend(true, {}, ins);


        F = function() {}
        F.prototype = sta;
        f = new F();

        // assign instances to the instance
        for(i in ins){
            f[i] = ins[i];
        }
        return f;
    };
}

var Vehicle4 = (function(){
    var that = {}

    that.instanceVar = {hey: 1}
    that.staticMethod = function(){
        console.log(this.instanceVar);
    }
    return that;
}())

var v31 = Object.create4(Vehicle4);
var v32 = Object.create4(Vehicle4);

v31.instanceVar.hey = 2;
v31.staticMethod();
v32.staticMethod();

在内存方面是否可以? 我的意思是: 在1000个对象实例中将有:

1 * STATICMETHOD 1000 * instanceVar

效率这么高吗?我想要注意,instanceVar将在每个对象中被修改,因此不会出现一个signle对象。

并且可能有任何内存泄漏?

var inherit = function(P, C) {
    return jQuery.extend(true, {}, P, C);
}

var Vehicle = function() {}
Vehicle.prototype = {
    init: function(){
        this.instanceVar = {hey: 1}
    },
    staticMethod: function() {
        console.log(this.instanceMember);
    },
    staticMethod3: function() {
        console.log(this.instanceMember);
    }
}

var SuperVehicle = function() {}
SuperVehicle.prototype = inherit(Vehicle.prototype, {
    init: function(){
        this.super.init.call(this);
        this.instanceVar2 = {hey: 1}
    },
    staticMethod: function() {
        console.log(this.instanceVar.hey);
        console.log(this.instanceVar2.hey);
    },
    staticMethod2: function() {
        console.log(this.instanceVar.hey);
        console.log(this.instanceVar2.hey);
    }
});
SuperVehicle.prototype.super = Vehicle.prototype;

var s = new SuperVehicle();
s.init();
s.staticMethod();
s.staticMethod2();
s.staticMethod3();

1 个答案:

答案 0 :(得分:1)

我可以肯定地告诉你它是正确的,你不会有内存泄漏,但是关于效率,我有一些疑问。
首先,你的静态成员不是很静态......它们只是被添加到对象的原型链中。整个原型继承系统依赖于每个对象递归地继承它的父亲原型这一事实。

因此,如果将属性添加到原始Object,例如:

Object.prototype.toString = function(){console.log("I am a primitive object");}

窗口中的所有对象都将继承此函数,它们将是“原始的”:))。

只有当你考虑到它只在内存中加载一次而不是每个实例加载时,你才可以将它称为“静态”方法,但你不能认为它是静态的,因为它与对象的当前实例交互(在其他面向对象语言中,如果将“this”关键字放在静态方法中,则抛出异常)

但是我没有在你的例子中看到所有这一点。

在您的示例中,您将“静态”方法固定到要创建的对象的原型中,但是您为每个对象实例重新创建原型。如果您创建两个或更多相同“类”的实例,它们将不会共享原型,但它们将各自具有相同的原型。

就在那里:

F = function() {};
F.prototype = sta;
f = new F();

每次使用此方法制作车辆时:

var myVehicle = Object.create4(Vehicle4);
var anotherVehicle = Object.create4(Vehicle4);

你为每个实例创建原型,这样做会破坏原型继承的目的。

我肯定会选择创建对象的经典方法(使用“new”运算符):

var Vehicle = function(val){this.instanceMember = val;}  
Vehicle.prototype = {   
    "staticMethod": function(){console.log(this.instanceMember);}   
}    
var v1 = new Vehicle("foo");  
var v2 = new Vehicle("bar");

通过这种方式,您可以轻松更改staticMethod并影响所有Vehicle实例:

Vehicle.prototype.staticMethod = function(){  
    console.log(arguments[0] || this.instanceMember);  
};

在您的示例中,如果更改staticMethod,则更改将仅应用于更改发生后构造的实例。 这就是说,在这种情况下,使用“静态”成员创建对象的旧经典方法效率更高。

P.S。 :对不起,如果我被带走了:))