function name(){
var fullName = "lawrence Turton";
function concat(name){
return "Hello Mr. " name;
};
return concat(fullName);
}
I am currently learning javascript. the sample code is from a youtube tutorial I am watching, the lesson is about embedding function inside a function, the 1st function is named "name" then the embedded function concat's parameter is also "name" then the return value is return concat(fullName);<--- this part really confuses me, because he used "name" thrice one when he gave a name for the the 1st function and the 2nd one as a parameter for the concat function and 3rd in the concatenated string, and since var fullName = "lawrence Turton" is define in fullName variable name, and i can't find a clear connection between "lawrence Turton"(string) and "name"(parameter)(variable),
my question here, is why can't the parameter in the function concat be (fullName) since "lawrence Turton" has already been defined in the variable FullName.
why not write it this way
function name(){
var fullName = "lawrence Turton";
function concat(fullName){
return "Hello Mr. " fullName;
};
return concat(fullName);
}
I also tried this and it worked
CodePudding user response:
why can not write it this way
As you probably already found out, you can. But it's recommended that you avoid it.
Why? You may ask. Well, you should be aware that inside your function concat
, the identifier "fullName
" refers to the function argument and not to the variable fullName
declared on the outter scope, this can be referred as "variable shadowing" and it's not considered a good practice (therefore we try to avoid it).
If you're willing to learn JS you will certainly come across a certain "Scope" topic, as it is one of the language's pillars. You can take a short read on it at W3Schools: JavaScript Scope, but I highly recommend that you dive deep into it while you're still starting to learn JS.
You can take a much, much deeper read on it here (You Don't Know JS Yet: Scope & Closures, by Kyle Simpson).
CodePudding user response:
The code example isn't that good because the function doesn't do what it says it does.
It's called name, but it returns a greeting to the name.
Also, you can recall .concat()
to add more things to the end of the message.
function name() {
var fullName = "lawrence Turton";
function concat(name) {
return "Hello Mr. " name;
}
return concat(fullName);
}
console.log(name());
console.log(name().concat("more stuff at the end."));
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
It would make more sense to use the functions as methods, so they can do more things.
In the example below, we can call .greet()
to get a greeting, or change the username with .setName()
.
If you look at the returned functions, we use an arrow function and an anonymous function. This is because in setName, we want to return this
context, so we can chain the methods. This allows us to do user.setName(name).greet()
. With an arrow function, this
works differently, and wouldn't work the same.
Here's a link to more details: This difference
const createUser = (username) => ({
greet: (greeting) => {
if(greeting) return greeting username;
return `Hi, ${username}`
},
setName: function(_username){
username = _username;
return this;
},
})
const user = createUser("John Smith");
console.log(user.greet())
user.setName("Fred")
console.log(user.greet())
console.log(user.setName("Steve").greet())
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
This functionality is similar to a class. With a class, it would look like this:
class User {
// the constructor is ran when you initialize the class.
constructor(username){
this._username = username;
}
greet(greeting){
if(greeting) return greeting this._username;
return `Hi, ${this._username}`;
}
setName(name){
if(name) this._username = name;
return this;
}
}
// You have to have new to create a new instance of the class.
const user = new User("John Snow");
console.log(user.greet());
user.setName("John Wick");
console.log(user.greet())
console.log(user.setName("John Smith").greet())
<iframe name="sif3" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
You can use which ever version you prefer.