Roland Soós
Roland Soós

Reputation: 3280

Javascript class properties behave as shared variable

I have the following declaration to easily create classes in Javascript. The Class is from this article: http://ejohn.org/blog/simple-javascript-inheritance/

JSfiddle: http://jsfiddle.net/xUCQp/

The problem is that it seems like that options of the object seems shared through the objects, but I need them to be instance variables. What is the problem with the code?

Code:

/* Simple JavaScript Inheritance
 * By John Resig http://ejohn.org/
 * MIT Licensed.
 */
// Inspired by base2 and Prototype
(function() {
    var initializing = false, fnTest = /xyz/.test(function() {
        xyz;
    }) ? /\b_super\b/ : /.*/;

    // The base Class implementation (does nothing)
    this.NClass = function() {
    };

    // Create a new Class that inherits from this class
    NClass.extend = function(prop) {
        var _super = this.prototype;

        // Instantiate a base class (but only create the instance,
        // don't run the init constructor)
        initializing = true;
        var prototype = new this();
        initializing = false;

        // Copy the properties over onto the new prototype
        for (var name in prop) {
            // Check if we're overwriting an existing function
            prototype[name] = typeof prop[name] == "function" &&
                    typeof _super[name] == "function" && fnTest.test(prop[name]) ?
                    (function(name, fn) {
                        return function() {
                            var tmp = this._super;

                            // Add a new ._super() method that is the same method
                            // but on the super-class
                            this._super = _super[name];

                            // The method only need to be bound temporarily, so we
                            // remove it when we're done executing
                            var ret = fn.apply(this, arguments);
                            this._super = tmp;

                            return ret;
                        };
                    })(name, prop[name]) :
                    prop[name];
        }

        // The dummy class constructor
        function NClass() {
            var $this = this;
            // All construction is actually done in the init method
            if (!initializing && this.init)
                this.init.apply(this, arguments);
        }

        // Populate our constructed prototype object
        NClass.prototype = prototype;

        // Enforce the constructor to be what we expect
        NClass.prototype.constructor = NClass;

        // And make this class extendable
        NClass.extend = arguments.callee;

        return NClass;
    };
})();

(function (scope, undefined) {
scope.ssTypeBase = NClass.extend({
        options: {
            test: 0
        },
    init: function(test){
         this.options.test = test;   
    }
});

    var a = new scope.ssTypeBase(1);
    var b = new scope.ssTypeBase(2);
    console.log(a.options.test,b.options.test);
})(window);

Upvotes: 0

Views: 561

Answers (1)

Yogesh Khatri
Yogesh Khatri

Reputation: 1210

Prototype properties are always shared between the objects. So in this case if you want options object to be instance variable than set options object inside constructor like this

(function (scope, undefined) {
    scope.ssTypeBase = NClass.extend({
        sharedOptionsObject: {
            test: 0
        },
        init: function(test){
            // create options object here, it will create seperate options object for each instance

            this.options = {
                test: 0
            }
            this.options.test = test;   
        }
     });
});

Upvotes: 1

Related Questions