Purposefully creating global variables is bad style, but accidentally creating global variables can be a downright disaster

Effect JavaScript : 68 Specific Ways to Harness the Power of JavaScript

    • More local less global
      • I am talking about local vs global scope. As a javaScript learner and after reading several books and blog notes I have come to the realization that global is BAD and local is Good. okay I am kidding. However if you are working with variables, for instance, try to prevent populating the global scope/object with your variables, since this could/may overwrite existing properties of the global object. Most of the time, when I create variables, I need them only for a certain function and nothing else. If  that is your case as well, just may it local dude or dudette.
      • For exampleee… instead of

[sourcecode lang=”javascript”]

///NO NO!!! here you are setting window.name = "Comfort Ajala". Even if you did not intend to do so.
function(){
name = "Comfort Ajala"
console.log(name)
return
}

[/sourcecode]

 

Do this

  • [sourcecode lang=”javascript”]
    //window.name = undefined (or already set by the environment) !GOOOD
    function(){
    var name = "Comfort Ajala"
    console.log(name)
    return
    }
    //window.name = undefined !GOOD
    [/sourcecode]

    • And my favvvvvvvvee!!! Closures
      • The only reason why I enjoy using them is because it took me 2 years to finally grasp what they are used for and how they are used….. geez.. I am slow. So closures, as simply as I can descripbe them, are  “inner functions” that can access variables living in the outer scope /parent function. I may piss off some js gurus by my weak definition but YOLO (do they use these anymore though 🤦🏿‍♀️🤦🏿‍♀️🤦🏿‍♀️). This is also a nice way to reuse variables, in my experience (humble), without the need to populate intentionally or unintentionally the global space e.g. For instance..

[sourcecode lang=”javascript”]

function makeaNigerianMeal(recipeName){
//below is the closure
return function printNigerianRecipeIngredients(…listofingredients){
var ingred, title, message = "", header, content //manual hoisting.. i think
title = `You are making ${recipeName}. The ingredients are `
for(ingred in listofingredients) {
message += listofingredients[ingred] + "\n"
}
header = document.createElement("h1"); header.innerHTML = title
content = document.createElement("p"); content.innerHTML = message
document.body.append(header)
document.body.append(content)
}
}

var d = makeaNigerianMeal("EBA")
d("Igbo Garri", "Hot Water")
var e = makeaNigerianMeal("MOI MOI")
e("Beans", "Tomato", "Tatashe", "Maggi", "Onions")

[/sourcecode]

 

        • Even after you have called the outer function and stored the “inner function” in the variableor e the inner function can still access the out function’s variables …. awesome right **in my geek voice👩🏿‍💻**
        • As defined in the book  “Functions that keep track of variables from their containing scopes are known as closures.”
      • Also, since closures store references to the variables in the outer scope, they can also manipulate their values….. cool but scary…
    • Variable Hoisting
      • “sighs in alien”
      • Hard for me to explain because I am yet to fully understand it, BUTTTT (wait there’s more..!), if you define a variable in let’s say a for loop so..

[sourcecode lang=”javascript”]

function printNameNTimes(name, N){

for(var i = 0; i < N; i++){
console.log(name)
}
console.log(i)
}

printNameNTimes("Comfort", 5) //should print name 5 times

[/sourcecode]

        • 2 years ago,  I would have assumed that var i were undefined outside the scope “context” of the for loop. But… nope. The console (last 1) would print 5. weeetttttt..
          • This is because of the aforementioned term HOISTING… basically all  variables in a function are “hoisted” = placed/declared at the beginning of the function like this:

[sourcecode lang=”javascript”]

function printNameNTimes(name, N){
var i; //hoisted
for( i = 0; i < N; i++){
console.log(name)
}
console.log(i)
}

printNameNTimes("Comfort", 5)

[/sourcecode]

This is why “i” is still accessible any where within the function

        • This does not apply to try and catch block scopes…. when you define a variable or update an already existing variable in the catch scope, outside of the scope it remains undefined or unaltered like so..

[sourcecode lang=”javascript”]
function tryCatch(){
var name = "Comfort Ajala";
try{
throw "exception"
}
catch(name){
name = "Tina Tery"
}
console.log(name)

}

tryCatch() //prints Comfort AJala; undefined

[/sourcecode]

  1. 21:51:38 04/28/2018 – UPDATE

    • THIS
      • The scope of “this” is always connected to the nearest enclosing function or in my words “parent function”
        • For instance

[sourcecode lang=”javascript”]
var person = {
trackID:0,
children:[{id:1, name:"me"}, {id:0, name:"you"}],
updateLast:function(old, newchild){
‘use strict’
this.children.map(function(child){
if(this.trackID == child.id)return newchild
else return old
}) // the reciever for the map method is "this.children", which has no property "trackID". so this.trackID will return undefined
}
}

person.updateLast({id:0, name:"you"}, {id:0, name:"you and me"})

[/sourcecode]

        • Solution –> create a variable “self” in the outer/parent function or add “this” as a second argument to the map method

[sourcecode lang=”javascript”]

var person = {
trackID:0,
children:[{id:1, name:"me"}, {id:0, name:"you"}],
updateLast:function(old, newchild){
‘use strict’
this.children.map(function(child){
if(this.trackID == child.id)return newchild
else return old
}, this) //the reciever is updated by the second argument which is not "this.children" but the reciever of the function/method updateLast, which is "person". Person has property "trackID" –> no ERRORS YEPPIE!
}
}

person.updateLast({id:0, name:"you"}, {id:0, name:"you and me"})

//or
var person = {
trackID:0,
children:[{id:1, name:"me"}, {id:0, name:"you"}],
updateLast:function(old, newchild){
‘use strict’
var self = this
this.children.map(function(child){
if(self.trackID == child.id)return newchild
else return old
}) //the reciever is updated by the second argument which is not "this.children" but the reciever of the function/method updateLast, which is "person". Person has property "trackID" –> no ERRORS YEPPIE!
}
}
person.updateLast({id:0, name:"you"}, {id:0, name:"you and me"})
[/sourcecode]

 

%d bloggers like this: