/    Sign up×
Community /Pin to ProfileBookmark

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???[/code]

Would appreciate any help anyone can provide. Thanks in advance.

to post a comment
JavaScript

8 Comments(s)

Copy linkTweet thisAlerts:
@TcobbMar 04.2014 — 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[/CODE]


If you rewrite it as:

[CODE]function Person(firstName) {
this._firstName = firstName;
};

var p = new Person("John");

console.log(p); //produces --> { _firstName: 'John' }[/CODE]
Copy linkTweet thisAlerts:
@grendallauthorMar 04.2014 — 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?
Copy linkTweet thisAlerts:
@TcobbMar 04.2014 — 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.
Copy linkTweet thisAlerts:
@TcobbMar 04.2014 — 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);[/CODE]


Once again, sorry for the original misinformation.
Copy linkTweet thisAlerts:
@grendallauthorMar 04.2014 — 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.
Copy linkTweet thisAlerts:
@007JulienMar 04.2014 — This to get something like java :
[CODE]function Person(firstName){
this.firstName=firstName;
}
var p1=new Person();
alert(p1+'nnConstructor: '+p1.constructor+'nnJson: '+JSON.stringify(p1));
var p2=new Person('Arthur');
alert(p2+'nnConstructor: '+p2.constructor+'nnJson: '+JSON.stringify(p2));
p1.firstName='Jean';
alert(p1+'nnConstructor: '+p1.constructor+'nnJson: '+JSON.stringify(p1));
p2.firstName='Jules';
alert(p2+'nnConstructor: '+p2.constructor+'nnJson: '+JSON.stringify(p2));[/CODE]
Copy linkTweet thisAlerts:
@TcobbMar 04.2014 — 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);[/CODE]
Copy linkTweet thisAlerts:
@grendallauthorMar 04.2014 — 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:

<i>
</i>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);
}

<i> </i>/**
<i> </i> * Public properties and methods
<i> </i> */
<i> </i>this.gender = gender; // public
<i> </i>// public getter/setters for firstName and lastName
<i> </i>this.__defineGetter__("firstName", function(){
<i> </i> return _firstName;
<i> </i>});

<i> </i>this.__defineSetter__("firstName", function(value){
<i> </i> _firstName = value;
<i> </i>});

<i> </i>this.__defineGetter__("lastName", function() {
<i> </i> return _lastName;
<i> </i>});

<i> </i>this.__defineSetter__("lastName", function(value) {
<i> </i> _lastName = value;
<i> </i>})

<i> </i>// Public methods
<i> </i>this.toString = function() {
<i> </i> return _firstName + " " + _lastName;
<i> </i>}

<i> </i>this.toStringInitials = function() {
<i> </i> return _initials();
<i> </i>}
}

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!
×

Success!

Help @grendall spread the word by sharing this article on Twitter...

Tweet This
Sign in
Forgot password?
Sign in with TwitchSign in with GithubCreate Account
about: ({
version: 0.1.9 BETA 5.2,
whats_new: community page,
up_next: more Davinci•003 tasks,
coming_soon: events calendar,
social: @webDeveloperHQ
});

legal: ({
terms: of use,
privacy: policy
});
changelog: (
version: 0.1.9,
notes: added community page

version: 0.1.8,
notes: added Davinci•003

version: 0.1.7,
notes: upvote answers to bounties

version: 0.1.6,
notes: article editor refresh
)...
recent_tips: (
tipper: @Yussuf4331,
tipped: article
amount: 1000 SATS,

tipper: @darkwebsites540,
tipped: article
amount: 10 SATS,

tipper: @Samric24,
tipped: article
amount: 1000 SATS,
)...