www.webdeveloper.com
Results 1 to 9 of 9

Thread: Asking for help with very short code excerpt: Why is the last line saying 'undefined'

  1. #1
    Join Date
    Feb 2014
    Posts
    12

    Asking for help with very short code excerpt: Why is the last line saying 'undefined'

    Code:
    function Person(firstName) {
        var _firstName = firstName;
    };
    
    Object.defineProperty(Person, "firstName", {
        get: function() {
            return this._firstName; 
        },
        set: function(value) {
            this._firstName = value;
        },
        configurable: true,
        enumberable: true
    });
    
    var p = new Person("John");
    
    console.log(p.firstName); // WHY IS THIS UNDEFINED???
    Would appreciate any help anyone can provide. Thanks in advance.

  2. #2
    Join Date
    Mar 2009
    Posts
    469
    Because your Person Constructor produces an object with no properties whatsoever.

    Code:
    function Person(firstName) {
        var _firstName = firstName;
    };
    
    var p = new Person("John");
    
    console.log(p);  //produces '{}'  -->  an empty object
    If you rewrite it as:

    Code:
    function Person(firstName) {
        this._firstName = firstName;
    };
    
    var p = new Person("John");
    
    console.log(p); //produces  --> { _firstName: 'John' }

  3. #3
    Join Date
    Feb 2014
    Posts
    12
    Thanks for responding, Tcobb.

    I guess I didn't phrase my question correctly, my apologies. I knew the 'p' instance had no properties. But if you look at my code, I did use Object.defineProperty to create a getter/setter, which didn't seem to take any effect, and that was what puzzled me.

    I declared _firstName the way I did to make it private, and I wanted the getter/setter to be the sole public methods. Do you see any reason why the Object.defineProperty didn't have any effect?

  4. #4
    Join Date
    Mar 2009
    Posts
    469
    Sorry --post deleted. The stuff I sent before was wrong in part.

    The problem is that your Person constructor object, as written, doesn't retain the value of John. You have to use the setter you created to place the value in there first.
    Last edited by Tcobb; 03-03-2014 at 11:27 PM. Reason: Correction

  5. #5
    Join Date
    Mar 2009
    Posts
    469
    Once again--my apologies for the last post. I was and am tired. What I said above was true, but the more fundamental problem is that Object.defineProperty requires that you send an object as the first argument. What you are doing is sending the Person constructor, a FUNCTION as the argument.

    Code:
    //This works--Object.defineProperty requires an obj as first ARG
    
    function Person(firstName){
        var _firstName = firstName;  //retains nothing
    }
    
    obj = new Person();
    
    Object.defineProperty(obj, "firstName", { //sending OBJECT as first ARG
        set: function (x) {
            console.log("Setting value");
            this.zap = x;
        },
        get: function () {
            console.log("getting value");
            return this.zap;
        },
        enumerable: true,
        configurable: true
    });
    
    
    obj.firstName = "John";
    console.log(obj.firstName);
    
    //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    /*This doesn't work--you are sending a Constructor rather than an object
      through Object.defineProperty as the first arg*/
    
    function Person(firstName){
        var _firstName = firstName;  //retains nothing
    }
    
    
    
    Object.defineProperty(Person, "firstName", { //sending FUNCTION as first ARG
        set: function (x) {
            console.log("Setting value");
            this.zap = x;
        },
        get: function () {
            console.log("getting value");
            return this.zap;
        },
        enumerable: true,
        configurable: true
    });
    
    var obj= new Person();
    
    //you can tell the setter and getter aren't working by the lack of the extra
    //message in those functions
    obj.firstName = "John";
    console.log(obj.firstName);
    Once again, sorry for the original misinformation.

  6. #6
    Join Date
    Feb 2014
    Posts
    12
    Tcobb, thank you for your continued response in trying to help me.

    I'm really confused. I come from Java, and all I'm trying to do is create a class that behaves properly as an OOP class. All I want is a class that can behave like this:

    var p1 = new Person("John");
    var p2 = new Person("Jane");
    console.log(p1.firstName); // and it would print 'John'
    console.log(p2.firstName); // and it would print 'Jane'

    OR

    var p1 = new Person();
    var p2 = new Person();
    p1.firstName = "John";
    p2.firstName = "Jane";
    console.log(p1.firstName); // and it would print 'John'.
    console.log(p2.firstName); // and it would print 'Jane'.

    The examples you showed me somehow does only the second. Is there a way to create a class that can do BOTH of the above and have firstName defined as a getter and setter internally?

    I'm also trying to just make an object with the capability of having private and public properties and methods. Once I can do that, I'm done with this part and I'm moving on, but I can't seem to accomplish this seemingly simple goal.

    Do you think you can show me a code snippet to make an object that meets the criteria I'm striving for? I don't think it will be exceedingly long. Thanks.

  7. #7
    Join Date
    Oct 2010
    Location
    Versailles, France
    Posts
    1,264
    This to get something like java :
    Code:
    function Person(firstName){
        this.firstName=firstName;
    }
    var p1=new Person();
    alert(p1+'\n\nConstructor: '+p1.constructor+'\n\nJson: '+JSON.stringify(p1));
    var p2=new Person('Arthur');
    alert(p2+'\n\nConstructor: '+p2.constructor+'\n\nJson: '+JSON.stringify(p2));
    p1.firstName='Jean';
    alert(p1+'\n\nConstructor: '+p1.constructor+'\n\nJson: '+JSON.stringify(p1));
    p2.firstName='Jules';
    alert(p2+'\n\nConstructor: '+p2.constructor+'\n\nJson: '+JSON.stringify(p2));
    Last edited by 007Julien; 03-04-2014 at 04:36 AM.

  8. #8
    Join Date
    Mar 2009
    Posts
    469
    This might do it for you as a solution:

    Code:
    function Person(fname){  //constructor
    
        Object.defineProperty(this, "firstName", {
    	    set: function (x) {
    		console.log("Setting value");
    		this.zap = x;
    	    },
    		get: function () {
    		console.log("getting value");
    		return this.zap;
    	    },
    		enumerable: true,
    		configurable: true
    		});
    
        this.firstName = fname;
    }
    
    var obj = new Person("George");
    
    
    console.log(obj.firstName);

  9. #9
    Join Date
    Feb 2014
    Posts
    12
    Tcobb, I found the solution. This will act as a real OOP data model as people would do in Java, C#, etc. It respects private and public properties and methods, as well as the use of getters/setters:

    Code:
    function Person(firstName, lastName, gender){
        /**
         * Private properties and methods
         */
        var _firstName = firstName; // private
        var _lastName = lastName; // private
        var _initials = function() { // private
            return _firstName.substr(0,1) + " " + _lastName.substr(0,1);
        }
        
        /**
         * Public properties and methods
         */
        this.gender = gender; // public
        // public getter/setters for firstName and lastName
        this.__defineGetter__("firstName", function(){
            return _firstName;
        });
       
        this.__defineSetter__("firstName", function(value){
            _firstName = value;
        });
    
        this.__defineGetter__("lastName", function() {
            return _lastName;
        });
        
        this.__defineSetter__("lastName", function(value) {
            _lastName = value;
        })
        
        // Public methods
        this.toString = function() {
            return _firstName + " " + _lastName;
        }
        
        this.toStringInitials = function() {
            return _initials();
        }
    } 
    
    var p1 = new Person("John", "Doe", "M");
    var p2 = new Person("Jane", "Bimbo", "F");
    
    console.log(p1.firstName); // shows 'John'
    console.log(p2.lastName); // shows 'Bimbo'
    console.log(p1.toString()); // shows 'John Doe'
    console.log(p2.toStringInitials()); // shows 'J B'
    Thanks for all your help, Tcobb!

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

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



Recent Articles