Results 1 to 10 of 14

Thread: [4.0.2a] Class inheritance keeps references to original fields

Hybrid View

Previous Post Previous Post   Next Post Next Post
    Looks like we can't reproduce the issue or there's a problem in the test case provided.
  1. #1
    Sencha User
    Join Date
    Jul 2007
    Posts
    5
    Vote Rating
    0
      0  

    Default [4.0.2a] Class inheritance keeps references to original fields

    Hi,

    I have 2 classes, one of which inherits another. I first create an instance of the Person class and populate its fields (test, items1, wrappedItems.wrap); the contents of the fields is alerted. After that I create a Developer and alert fields values; the inherited fields MUST be empty - but they are NOT (except for the "test" fields).

    The example demonstrates the behaviour. My understanding is that the second alert should output all NULLs/empty values.

    Code:
    Ext.define('Person', {
        test: null,
        items1: [],
        wrappedItems: {
            wrap: null
        },
    
        constructor: function(name) {
            this.test = name;
            this.items1.push(name);
            this.wrappedItems.wrap = name;
    
            alert("Person: " + this.items1.toString() + ", " + this.test + ", " + this.wrappedItems.wrap);
            return this;
        }
    });
    Ext.define('Developer', {
        extend: 'Person',
    
        constructor: function() {
            alert("Developer: " + this.items1.toString() + ", " + this.test + ", " + this.wrappedItems.wrap);
            return this;
        }
    });
    
    var person = new Person("test123");
    var dev = new Developer();

  2. #2
    Sencha User ykey's Avatar
    Join Date
    Mar 2010
    Location
    USA
    Posts
    245
    Vote Rating
    28
      0  

    Default

    This is not a problem with inheritance. It appears to be a problem with object properties. But not sure it is a problem or just a misunderstanding.

    For example:

    Code:
    var fn = function() {};
    var fn2 = function() {};
    	
    Ext.define('Person', {
    	name: 'Default',
    	data: {},
    	fn: undefined,
    	
    	constructor: function(name, fn) {
    		if (name) {
    			this.name = name;
    			this.data.name = name;
    		}				
    		
    		if (fn) {
    			this.fn = fn;
    		}
    	}
    });
    
    Ext.onReady(function() {					
    	var person = Ext.create('Person', "Name", fn);						
    	var person2 = Ext.create('Person', "Name2", fn2);
    				
    	console.log(person.name);		// Expected
    	console.log(person.data.name);	// Failure, expecting: Name  Actual: Name2
    	console.log(person.fn === fn);  // Expected
    
    	console.log(person2.name);		// Expected
    	console.log(person2.data.name); // Expected
    	console.log(person2.fn === fn2);  // Expected
    	
    	console.log(person.fn !== person2.fn); // Expected
    });

  3. #3
    Sencha User evant's Avatar
    Join Date
    Apr 2007
    Location
    Sydney, Australia
    Posts
    19,007
    Vote Rating
    936
      0  

    Default

    @ykey is correct

    When you specify a property in a class definition it gets shared across all instances. Doesn't matter for strings and numbers, but you need to be careful with arrays/object literals.
    Twitter - @evantrimboli
    Former Sencha framework engineer, available for consulting.
    As of 2017-09-22 I am not employed by Sencha, all subsequent posts are my own and do not represent Sencha in any way.

  4. #4
    Sencha User ykey's Avatar
    Join Date
    Mar 2010
    Location
    USA
    Posts
    245
    Vote Rating
    28
      0  

    Default

    So the correct way to do this would be to create the array/object literals in the constructor or elsewhere in the instance.

  5. #5
    Sencha User
    Join Date
    Jul 2007
    Posts
    5
    Vote Rating
    0
      0  

    Default

    @ykey
    Thank you, you've shown the exactly same behaviour in your code.

    @evant
    I actualy thought those "class properties" were private to each class instance. Shouldn't be they (in normal OOP)? Instead they are more like "protected static".

    So,

    1. Is this the standard behaviour which won't change in next versions? It woud be nice to have the clarification somewhere @ http://docs.sencha.com/ext-js/4-0/#/guide/class_system

    2. While the suggestion to put all the init code into constructor is ok as a workaround, this is somewhat clumsy. I have a class extended from Ext.window.Window, which defines "items" property. It is pretty big and I'd need to put it into constructor now, otherwise I can't create multiple instances of the class

    Thank you in advance.

  6. #6
    Sencha User ykey's Avatar
    Join Date
    Mar 2010
    Location
    USA
    Posts
    245
    Vote Rating
    28
      0  

    Default

    I am pretty sure I have narrowed this down and it really just comes down to standard JavaScript and prototypal inheritance.

    Code:
    function Person(name) {
    	if (name) {
    		this.name = name;
    		this.data.name = name;
    	}
    }
    
    Person.prototype.name = 'Default';
    Person.prototype.data = {};
    
    var person = new Person();
    var person2 = new Person('Name2');
    
    console.log(person.name);       // Default
    console.log(person.data.name);  // Name2
    console.log(person2.name);      // Name2
    console.log(person2.data.name); // Name2

    Ext.Class constructor is calling Ext.Base.implement with provided arguments which just adds them to the prototype.

    Code:
    Ext.define('Person', {
    	constructor: function(name) {
                    if (name) {
    		    this.name = name;
    		    this.data.name = name;
                    }
    	}
    });
    
    Person.implement({
    	name: 'Default',
    	data: {
    		name: 'Default'
    	}
    });
    
    var person = new Person();
    var person2 = new Person('Name2');
    
    console.log(person.name);          // Default
    console.log(person.data.name);   // Name2
    console.log(person2.name);        // Name2
    console.log(person2.data.name); // Name2
    Last edited by ykey; 26 Jul 2011 at 8:47 PM. Reason: Fixed examples

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •