My code is very similar to the basic solution. With the one exception that I did not save firstAndLast as a separate variable. Can someone please review my setFirstName code? Is it necessary to save firstAndLast off first? Or can my code work (if tweaked)…?
Your code so far
var Person = function(firstAndLast) {
// Complete the method below and implement the others similarly
this.getFullName = function() {
return firstAndLast;
};
this.getFirstName = function() {
return firstAndLast.split(" ")[0];
};
this.getLastName = function() {
return firstAndLast.split(" ")[1];
};
this.setFirstName = function(first){
this.firstAndLast = first + " " + firstAndLast.split(" ")[1];
return firstAndLast;
};
};
using Object.keys(this) in your Person creator, we should see only six keys: one for each function (three setting functions, three getting functions).
We need to store that firstAndLast somehow, but we can’t save it onto this.firstAndLast, as that will give us another Object.key, thus failing that test.
The ONLY WAY to affect that firstAndLast is through those getters and setters – thus it CAN’T be stored as an object property.
Hmm… What to do, what to do? Actually, this is a great example to work with understanding variable scope. See, variables created within a function are only available within that function, or any functions nested within it. How does that help? Try something like this:
var Person = function(firstAndLast){
// Let's create all three setters:
this.setFullName(firstAndLast){
// ... Do stuff. Important thing to note: we can use the variable myName here! This
// function is defined within our Person, so it has access to variables defined there.
};
this.setFirstName(first){
//...
};
this.setLastName(last){
//...
};
this.getFullName(){
//...
};
this.getFirstName(){
//...
};
this.getLastName(){
//...
};
var myName = firstAndLast;
};
So,within the function, we can access myName – this is a variable, and not a property on Person. But outside of Person, that variable doesn’t exist.
Thanks @snowmonkey. I ended up doing exactly what you said. And I have a follow up question.
Are you saying I am not allowed to use this.firstAndLast b/c the FCC testing scripts is looking for a specific type of solution? That is, in the real world, I could’ve used this.firstAndLast?
Thank you!
My final code in case anyone is interested:
var Person = function(firstAndLast) {
// Complete the method below and implement the others similarly
let fullname = firstAndLast;
this.getFullName = function() {
return fullname;
};
this.getFirstName = function() {
return fullname.split(" ")[0];
};
this.getLastName = function() {
return fullname.split(" ")[1];
};
this.setFirstName = function(first){
fullname = first + " " + fullname.split(" ")[1];
return fullname;
};
this.setLastName = function(last){
fullname = fullname.split(" ")[0] + " " + last;
return fullname;
};
this.setFullName = function(firstAndLastlast){
fullname = firstAndLastlast;
return fullname;
};
};
var bob = new Person('Bob Ross');
bob.getFullName();
you could, sure, but you may not want to. In the real world, do you want something outside of your object to be able to modify values within that object? There are cases where that makes sense, but in most cases, you want to build “black-box” code – you want to be able to control how things get in, and what things get OUT, of your object.
There are pros and cons to each approach. Personally, I like to “lock down” my objects, and only allow getters and setters to effect my data, but there are times where publicly accessible properties make sense.
I would highly recommend some further reading: https://crockford.com/javascript/private.html (Doug Crockford is one of the Grand Masters of the javascript world, and a name to know). Also, a great book about scope (and also about effective design patterns), is Pro Javascript Design Patterns by Ross Harmes and Dustin Diaz.
I believe that setting up myName is superfluous since firstAndLast actually is a local variable. When a function sets up its execution context it includes in that a variable object. this is the case even when the function is invoked with the new operator. The variable object provides several local variables to the function’s execution context:
this
arguments array-like object
and each of the function parameters as separate variables
So it is perfectly legit to simply use firstAndLast without reassignment. Even though we are invoking the function with the new operator, each new object instance gets those parameters as local variables.
The problem with this exercise is that usually the methods would be put on the prototype to conserve memory. But if you do that then the methods can no longer access these private variables and you’re left with creating that undesirable public variable.
Notice in Crockford’s article that you cited, he always assigns the param to this.member (which is publicly available) for this very reason. In the PUBLIC section the reason is explicit. But in the PRIVATE section of his article he is still compelled to do it.
Not the way you were originally using it. firstAndLast doesn’t exist on the this object unless you explicitly assign it there. firstAndLast does exist as a local variable (local to the function’s execution context) so that’s legit.