Category Archives: Javascript

JavaScript Quirks In a Nutshell

When I was first learning JavaScript I would come across posts about how weird (or bad) the language was, and since it was the first programming language I learned and didn’t have anything else to compare it with, I didn’t understand why some people had a negative opinion of the language.

This is an attempt to assemble  a list of those JavaScript quirks that give it a bad wrap, and were confusing to me when I was learning, as well as key concepts that are vital to understand in order to write good (i.e. working) JavaScript code.  My goal is to create a concise list that would be helpful for those learning the language to reference in order to understand some of the “weird” behavior of JavaScript, and how to use the language more effectively while not having to learn these things “the hard way”, or learning them way too late.  The list is meant to be an overview to make the student aware of these things and serve as a launching point for further exploration and research.

NOTE: This list is a work in progress and constantly expanding.  It will be updated and is under construction, so if there are other quirks or important concepts that you would like to see included that would help one write more informed and well-written JavaScript code, drop a note in the comments section.  It would be great to have a one stop shop that has as many of the quirks and confusing things about JavaScript in one place for people who are learning to have as a reference.

Table of Contents:

  • …more to come

THE CREATION AND EXECUTION PHASE:

  • When the JavaScript Engine runs in the browser, it runs in two phases – a Creation Phase and an Execution Phase.
  • A Creation Phase and Execution Phase is run every time the JavaScript for the app initially loads to create the Global Execution Context, and also runs for each successive call to any function to create that function’s Execution Context.
Terms:
  • Creation Phase:  All variable names (including the built-in this variable), objects and functions are created and stored in memory for use in the Execution Phase.  For example, on an app initialization (first load), the global window object is created and variable names, as well as functions in the code are created, stored in memory space and attached to the global window object.  A Global Execution Context is created and the this keyword is created and setup.  In addition, an outer reference to the immediately outer Execution Context is set up which allows access to variables and objects in that context (In this case there wouldn’t be an outer context, since the global context is the top most level).
  • Execution Phase:  The JavaScript code is then run and executed, line by line, without stopping or pausing.
  • Execution Context:  The environment that is created during the Creation Phase that the JavaScript code runs inside of during the Execution Phase.  It defines the variables, objects, functions and function arguments which are available and accessible, as well as the scope chain, and the this value.

*A new Execution Context is created for every function that runs in JavaScript which entails running through a Creation and Execution Phase for it, and setting up an outer reference to the immediately surrounding Execution Context which allows access to the outer context’s variables and objects (see Scope Chain below for more details). 

  • Execution Stack:  A model or data structure in the JavaScript engine which keeps track of the order of the execution of code and it’s current Execution Context.  Every time a function is called in the code, a new Execution Context (or Call Stack) is created and placed at the top of the Stack.  JavaScript is a single threaded language (which means it runs one call stack at a time).  When the execution of the function is completed, that Execution Context is “popped” (removed) off the top of the Stack, and the code of the previous Execution Context on the Stack beneath it is run, picking up from where it left off from before the code from the popped Execution Context began running.  (Further resources: see this great Youtube video lecture on the Call Stack and the Event Loop)

HOISTING:

  • Refers to the storing of functions and variables in memory by the JavaScript engine during the Creation Phase (see above) before the code actually runs.   All variables are initially stored and set to a value of ‘undefined’, but all functions are stored complete in memory (including the declaration of their name as an identifier for a space in memory to look, and their value (the body of the function, etc.)).
  • This is why you can define a function in your code AFTER you actually call it, but variables will return undefined if they are referenced before their declaration in the code.

Example:

// Calling the function in the code before it's defined:
hoistedFunction();

hoistedFunction() {
  console.log("The function ran and worked!");   
}

In the above Example, the call to hoistedFunction() will log "The function ran and worked!" even though it is called before it is defined.  This is because during the Creation Phase, all functions defined in the code are “hoisted” into memory and made available before the code actually is run in the Execution Phase.  Note that this is different from variables, which are initially set to undefined and cannot be referenced before they are assigned in the code.


THE SCOPE CHAIN:

  • If a variable is used in a function and a value is not found for it inside that function’s scope or block, then JavaScript will look for it’s value in the function’s outer environment context.  If the value is not found there, then it will search the environment of the next outer context, and keep going all the way to the global environment to look for the value for the variable.
  • It should be noted that looking for an outer scoped variable’s value stops when the first match is found.
  • It’s possible to access a variable directly on the global scope with window.[variable name].
  • Lexical Scope:  Scope that is assigned based on where variable and function declarations are written in the code (i.e. functions written inside other function body blocks, variables declared in the global space outside of any function blocks, or inside a function’s scope because they are declared in the body, etc.).

Example of traversing the scope chain:

// a variable created at the top level execution context (global):
const globalVar = "from top level";
// Execution Context is created for initial function:
const exampleFunction = function() {
  const outerVar = "from outer context.";
   // A new Execution Context is created when this inner function runs, but it has access to the immediate outer context it's created in, and also the outer context of it's outer context up the scope chain to the top global level, etc.:
  (function() {
    console.log(outerVar); 
    console.log(globalVar);   
  })();
}

exampleFunction();
// When called, the function logs "from outer context" and then "from top level" - the JS Engine went up the scope chain to find outerVar and globalVar and look for it's value all the way up to the top level global context since they were not defined and assigned a value in the inner function block.

*NOTE THIS QUIRK:  When not in strict mode (‘use strict’), if a variable is not declared with var/let/const but assigned a value, then a variable of that name will be automatically created and implicitly declared in the global scope.

Example:

undeclared = 5;

// A global variable undeclared is created and assigned the value of 5 automatically by JavaScript.
NOTE: If 'use strict' is implemented, then a ReferenceError will be thrown and automatic declaration will not occur.

eval():

  • Built in function in JavaScript that takes a string as an argument, and treats the contents of the string as code that was authored code at that point in the program, consequently altering the corresponding Lexical Scope.
  • Can be used to execute dynamically created code (that’s not
    hard coded initially).
    In other words, you can dynamically generate code that is not hard coded at author time and eval() will inject it as if it were hard coded at author time – this is a way to cheat Lexical Scope (code that is scoped based on where it was authored), but has performance issues and is bad practice.
  •  If a string of code that eval(..) executes contains variable or function declarations, the existing lexical scope in which the eval(..) resides will be modified.
  • Note from reference book listed below: “The use-cases for dynamically generating code inside your program are incredibly rare, as the performance degradations are almost never worth the capability.”

Reference: You Don’t Know JS: Scope & Closures, Chaper 2.


PRIMITIVE TYPES:

Terms:
  • Type:  A category identifier for a piece of data which can be used by the JavaScript engine to determine how to handle the piece of data and what operations can be performed with it. For example, a Number type is assigned to a piece of data that is represented by an integer.  Since the data has a type of Number, JavaScript knows that it can do things like arithmetic with it and another piece of data of the same type, etc.
  • Primitive Type:  Represents a single value in JavaScript that is not an Object type.  (Everything in JavaScript is either a Primitive or an Object).
  • DYNAMIC TYPING:   JavaScript is a dynamically typed language.  The engine figures out and determines what type of data a variable holds (without having to declare it explicitly) while the code is running.  It’s possible for a variable to hold different types of values while the code is running.  You don’t specify what type of data is in a variable (you just use var/const/let, and JavaScript figures out what it is – a Number, Boolean, String, etc.).

6 Primitive Types:

  • Undefined: lack of existence (don’t use this or set variables to this)
  • Null: lack of existence – use this to set variables to nothing (let the engine use undefined). Null is not coerced by JS to 0 for comparisons, but coerced to 0 in other contexts (i.e. with Number() function).

*What is the difference between NULL and UNDEFINED?

null is read by JavaScript to mean that there is no value, but the developer intends it that way and set it to null explicitly (i.e. let x = null;), whereas undefined may throw an error as being an unintended absence of value from not assigning anything to the variable (i.e. let x;), and then accessing it (i.e. console.log(x); ), or by simply not declaring it at all in the first place.  Setting a value to undefined explicitly is not considered good practice.  If you want a value to be assigned as undefined or empty, then set it to null in the code.

  • Boolean:  A primitive that has a value of true or false.
  • Number:  An Integer or floating point number (decimal), i.e. 5 or 5.23 etc.
  • String:  Sequence of characters inside quotes (single or double).
  • Symbol (used in ES6 ):  May not be supported by some browsers.

THE EVENT LOOP:

Terms:
  • Event Loop:  A constantly running process that checks a Task Queue for any callbacks registered which are associated with asynchronous operations or Event Listeners, and pushes them to the Execution Stack whenever it is empty.
  • Task Queue: A built-in feature of the Event Loop that keeps track of and stores registered callbacks for any asynchronous operatons (network requests for example) or Event Listeners (for a ‘click’ Event when a user clicks a specified button for example) which are ready to be run and awaiting a push to the Call Stack from the Event Loop.
  • Web API:  Features and methods that come built-in from the browser and that are provided and made accessible to the JavaScript Runtime Engine  so you can access them in your JavaScript code.  Examples are multi-threaded operations made available by Web API methods such as setTimeout() or AJAX requests over the wire using the XHR (XmlHttpRequest) Object provided by the browser.  Javascript is a single-threaded language, so these features and methods allow access to additional threads which can be used to perform longer-running operations while not blocking the running of JavaScript code.
  • Thread:  A line (or “thread”) of instructions sent to a processor from an application. The set of instructions can be abandoned and come back to later where the processor left off with them last and then complete them (called context switching).
  • Execution Stack (aka Call Stack, or just Stack):  see Creation and Execution Phase entry above).
  • Callback:  a function that is registered to run when an asynchronous operation completes.  These are collected in the Task Queue, which the Event Loop constantly checks to push them to the Stack to run.
  • Event Listener:  A feature which can be accessed in JavaScript code with [element].addEventListener([event], [callback]) that registers a callback function to be run when a specified event occurs.  The browser throws events that can occur which are associated with HTML elements in the DOM as the user interacts with the application (i.e. a ‘click’ event is thrown by the browser when a user clicks on a button element on the page).  The callback registered is then pushed to the Task Queue when the event occurs and the Event Loop will see it and run the callback.

What the Event Loop does:  It’s job is to look at the Task Qeue and the Execution Stack in the JavaScript Runtime and if the Stack is empty, and there is anything (i.e. any callbacks registered) in the Task Queue, then it pushes that callback function to the Execution Stack for JavaScript to run it.


CLOSURES:

  • A closure is a feature of JavaScript which enables a function that is called outside of the scope it was created in (and after that scope’s execution context is cleared from the Stack) to have access to variables and values that were created in it’s original lexical scope (the function block where it was defined).
  • Basically, it’s an encapsulation of values and variables from a scope where a function was defined, so that when that function is passed as a value and called outside of that scope (i.e. returned and used elsewhere in the code), those variables and values remain accessible to it and their values in tact and defined as they were in the original scope.
  • Closures are a commonly used feature whenever you want to pass functions as values to be called at a later time in the code which maintain references to variables in the scope they were created in, and are also used in creating JavaScript Modules, for example, where you can expose methods on a returned object that have references to private, protected, internally defined and scoped variables by invoking a wrapper function which creates a closure, encapsulating those variable values which the exported object methods can reference.
  • IIFE’s (Immediately Invoked Function Expressions) can be used to create a scope and consequently a closure (this can be useful in a for loop, for example to capture the value of i).

Example Use Case with Asynchronous operation in a for loop using a Closure to capture the value of i:

for (var i = 0; i <= 5; i++) {
   (function(i) {
      fetch(`/page${i}`)
        .then(() => {
           console.log(`fetched page ${i}`);
        });
   })(i);
}
// The value of i will be encapsulated by the IIFE on each loop iteration and a reference maintained to it in the asynchronous callback (otherwise the value of i would always be the terminal value since the async function callback runs after the loop is finished and references the value of i at that time.

REVEALING MODULE PATTERN Use Case:

function userModule() {
   const username = "Brent";
   const eyeColor = "brown";

  function username() {
   console.log( username );
  }

  function eyeColor() {
    console.log( eyeColor );
  }

  return {
   username: username,
   eyeColor: eyeColor
  };
}
// Invoke the function to create a closure:
const user = userModule();

user.username(); // "Brent"
user.eyeColor(); // "brown"

// The userModule invocation exposes functions in that module that utilize closures to retain references to private protected variables and values which can be accessed when the exposed functions are called outside of the context they were defined in.

‘USE STRICT’:

  • By typing 'use strict;' in your code, this changes JavaScript’s un-opinionated, loose rules and flexible behavior by preventing type coercion and requiring more explicit syntax.
  • Considered good practice to implement in production code in order to catch potential errors.

Examples of behavior with ‘use strict’:

'use strict'; 

a = 1; // throws an error since var, let, const is not used to declare it. 

17 = '17'; // will throw an error since type coercion is turned off and the string '17' will not be converted to a number or vice versa.

// When calling a function the shorthand way (instead of using fn.call()), this is set to undefined in strict mode:

fn("arg"); // this is undefined.

// Normally when not using strict mode, this is set to the window object in a shorthand function call.
// See this article recommended by Dan Abramov:
Understanding Javascript Invocation and "this" by Yehuda Katz

MISC:

  • Everything in JavaScript is an Object or Primitive data type.
  • JavaScript compiles (translates the human readable code to machine code that the computer can understand and execute) just before execution, as opposed to other languages which are compiled well before.

External Resources/Further Reading:

  • You Don’t Know JS: Up & Going by Kyle Simpson – an excellent book series on Javascript to gain a more sophisticated understanding of how the language works – but written in a way that’s not to dense or difficult to digest.  E-book format is free to read online.
  • wtfjs.com – Funny website with many examples of strange JavaScript behavior.
  • Good article on Scope and THIS – from Digital Web Magazine by Mike West.

 

…More Items Coming… This list will continue to be updated.

Items planned for future updates:

  • Type Coercion
  • truthy and falsy concept and rules
  • Logical Operators
  • Comparisons
  • This keyword
  • New keyword
  • Prototypal Inheritance
  • The Prototype Chain
  • ES6 Classes
  • Promises
  • Synchronous vs. Asynchronous execution
  • Web APIs that add features and asynchronous functionality to JavaScript

Event Bubbling in a Nutshell

When reading through Stack Overflow posts having to do with Javascript, I sometimes came across the term Event Bubbling and never knew what it was really.  I decided to sit down and spend some time learning about it so I wouldn’t be puzzled anymore by it.  My main learning resources were two excellent Youtube tutorial videos:  Javascript Event Capture, Propogation and Bubbling by Wes Bos and Event Bubbling by The Net Ninja.   This is an excellent article as well on the topic.  I recommend you at least watch the Youtube tutorials, but I am going to attempt to boil the subject down into a single post here.

Event Bubbling In a Nutshell:

  • Events (such as ‘click’ events, for example) are registered not only by the target element where they originate, but by all of that element’s parents all the way up to the global element (i.e. the Window/Browser).
  • An Event occurs (a ‘click’, for example) and the click event is registered (this means recorded or noted and recognized by the browser).  The registered click event then goes from the Window Object down through the child elements and is registered on each during a ‘Capture Phase’ (<html> –> <body> –> <div> –> <form> –> <button>, for example) to find the Target Element (where the click event originated from, i.e. what element was clicked).  Once the click event has registered on the Target (‘Target Phase’), it then bubbles back up the DOM Tree (‘Event Bubbling Phase’) and is registered on all parent elements up through the Window Object triggering any Event Listeners or Handlers in the process.

Why it’s important to understand: 

  • To avoid unintentional Event Handle triggering on parent elements of the target, or to intentionally incorporate handling the event on a parent element. 
  • If there are any identical Event Listeners on the parent elements of the Event Target, then their respective Event Handlers will be triggered.  A click event on element A will trigger element A’s Event Handler as well as Element A’s parents’ Event Handlers for a click event.  

For more information and examples, keep reading:

Definitions:

  • Window Object: My non-technical understanding is to just think of it as the browser or the window you have open in the browser.  It contains all of the elements on the page.
  • Event Target:  The element that the Event originated from (i.e. the element that was clicked, for example).
  • Event Capture: The process of recording events that occur starting at the top of the DOM (the Window Object) and down through the parent elements related to the Event Target.
  • Event Propagation: To propagate, literally means to spread and promote widely.  The event is ‘spread widely’ and registered throughout the DOM tree from the top (Window Object) down to the event target, and back up to the top again.
  • Event Bubbling: The process in which the Event is registered on each successive parent element of the Event Target element all the way up to the Window Object.
  • Event Target Phase: This occurs in between the Capture and Bubbling Phase during Event Propagation.  During this phase, any listeners on the Event Target for the Event and their respective functions will be triggered and invoked.

The Process:

Event Bubbling happens in the course of what’s called Event Propagation, which has three main parts:

  • The Capture Phase: The event is recorded from the top of the DOM and down to find the event target.
  • The Target Phase: The Event is registered on the Target (the element it originated from) and any Listeners or Handlers are fired.
  • The Event Bubbling Phase:  After the Capture and Event Target Phase, the event is registered on each parent element of the Event Target, in order, up through the DOM Tree to the Window Object.

Important Note: Branch paths in the DOM for Events during Event Bubbling are static:  If the DOM tree is modified after the Event Listeners have been assigned, the modified DOM tree or added elements will not be used or included in the Event Bubbling process.

For example, if the handling of the Event involves creating/appending/inserting an additional parent element of the Event Target, then the inserted parent element will not register the Event as it bubbles up the DOM tree on future click events originating from the Event Target.  The Event will bubble only up through parent elements present in the DOM Tree when the Event Listener for that target was assigned (for instance, at the loading up of the page).

Additionally, an Event Listener that is assigned to a class of elements will not be applied to any elements of that class that are later added to the DOM Tree.

Scenarios Where Understanding Event Bubbling Can Help:

Example (consider the following HTML which contains a list of items with buttons that give the user the option to remove the item from the list, or add an item to the list):

<div>
  <ul id='theList'>
     <li id='item_copy'>List Item
       <button class='btn_remove'>Remove</button>
     </li>
     <li>List Item
        <button class='btn_remove'>Remove</button>
     </li>
  </ul>
  <button id='btn_add'>Add Item</button>
</div>

Now, the Javascript to assign Event Listeners and Handlers:

// Add a list item to the list when Add Item clicked:
<script>
const parent_el = document.getElementById('theList');
const li_content = document.getElementById('item_copy').innerHTML;
const add_btn = document.getElementById('btn_add');

add_btn.addEventListener('click', () => { 
    let created_li = document.createElement('li'); 
    created_li.innerHTML = li_content;
    parent_el.appendChild(created_li); 
});
// Assigns click event listener and handler for the remove buttons currently on the page: 
const remove_btns = document.getElementsByClassName('btn_remove');

// A click on .btn_remove removes item from the list: 
 Array.from(remove_btns).forEach(function(btn) {
     btn.addEventListener('click', (e) => {
     let target_btn = e.target;
     let li_to_remove = target_btn.parentElement;
     li_to_remove.remove();
     });
 });
</script>

In the above example, the remove buttons will not work on list items that are added by the user with the Add Item button.  The reason is because when the Event Listeners were assigned to the Remove buttons, the DOM  Tree did not include the added list items created when the user clicks Add Item.  So the Event Listeners and click handlers don’t exist on the newly created list items.

This is where Event Bubbling can come in to save the day.  You use this process to your advantage to solve this problem by assigning the Event Listener and Handler for the click to the parent element of the user added list items (this would be the <ul> with the id of “theList”).

This way when the user clicks on the remove button on the newly created list item, the click event will bubble up through the parent elements and the Event Listener on <ul> “theList” will be ready and waiting for it.  Once the click on the newly added remove button registers on <ul>, it’s target can be found and the remove element function fired.

Example:

 // Grab the pre-existing parent element (<ul>): 
 const the_List = document.getElementById('theList');
 // Add the listener to #theList and pass in the 
    event:
 the_List.addEventListener('click', (e) => {

 // Check to see what the Event Target of the caught    
    click was.
 // If it was the remove btn, then remove the list
    item:
 if (e.target.className == 'btn_remove') {
     let list_item = e.target.parentElement;
     list_item.remove();
     }
 });

Now, the list items added by the user after the page loads will be removed when the user clicks the remove button.  The <ul> ‘theList’ catches the click event as it bubbles up the DOM tree and handles it by finding the Event Target (the remove button clicked) and removing the parent element of it (the list item).

Hopefully, this summary on Event Bubbling will prove to be helpful to those wanting to get their feet wet in the subject and start to understand what it is and how understanding it can help solve problems like this that come up in your code.

A Good Javascript Tutorial on Udemy (It’s great!)

When scouring Youtube and the internet in search of the best Javascript tutorial I could find, I noticed repeat recommendations for certain courses on Udemy that included Anthony Alicea’s course, “Javascript: Understanding the Weird Parts.

When you see something recommended multiple times from independent and varying reputable sources, it’s a good idea to check it out.   I promptly purchased the course for $10.00 (it’s normally about $15.00 I believe) on a New Year’s sale and began devouring the course.  I completed it yesterday, and I can say that the course is more than worth it and it lived up to all of the recommendations.

The teaching approach taken by Mr. Alicea is to examine how Javascript works “under the hood.”  There is an emphasis put on “understanding” over “imitating.”  The method is very effective and is employed with great skill.  I really did feel like I was learning the “Why” in addition to the “How.”  Concepts and terms are broken down and explained in plain English to the student with prompts like “Big Word Alert”, where an intimidating term like “Immediately Invoked Function Expressions” is explained in a concise and straight-forward manner, de-mystifying any jargon.  The course was very well thought out and logically structured as well.

Before taking the course, you should know some basic Javascript.  I started with this excellent tutorial(link) by Bucky Roberts on his channel, thenewboston, before taking Alicea’s course on Udemy.    The tutorial is concise and to the point while being slightly entertaining; all of Bucky’s tutorials are really well done and great for beginners who don’t know where to start.  After going through that beginner’s tutorial, I was able to keep up in the Udemy course and not be lost from the beginning.

Topics covered in the Udemy course included (very partial list!):

  • Execution Contexts
  • The Execution Stack
  • Scope Chains and Namespace
  • Precedence and Associativity (for Operators)
  • Closures
  • IIFEs (Immediately Invoked Function Expressions)
  • First Class Functions
  • Functional Programming
  • Prototypes and Prototypal Inheritance
  • Function Constructors
  • Examining Frameworks/Libraries (JQuery)

The lectures on the Execution Stack, Execution Contexts and Closures were invaluable to me and clearly explained more advanced concepts and ways that the Javascript Engine works that would have taken me much longer to understand or become aware of without taking the course.  I’d almost say it was worth it for those lectures alone, but the rest of the material was just as informative and helpful.

The Deep Dive Into Source Code section to get what the teacher calls an “opensource education,” was eye opening and very interesting.  Taking a look at famous libraries and frameworks like JQuery and underscore.js can be intimidating, but Alicea breaks some of the code down and shows you how to get started taking it apart in order to learn from it.  A great source that the course exposed me to was the annotated version of underscore.js which can be found here  and the uncompressed development version of JQuery which can be found here.  These versions of the libraries are commented and annotated to explain what is happening in the code.

I can’t recommend the course highly enough if you have an interest in learning Javascript.  Now that I’ve taken Bucky Robert’s beginner tutorial and Javascript: Understanding the Weird Parts, I think I have a solid foundation in Javascript to build on in the future as I continue to learn more about the language.  If you’re interested in getting an idea of what is taught in the beginner’s tutorial and the course, you can look at my notes that I took while studying and going through them.  They are very rough and basic in format; just in a simple text file, they were just meant to help me remember and digest some of the concepts, but they might prove helpful to look through if you’re learning or interested in taking the courses.

JAVASCRIPT NOTES

 

PHP Variable Scope (and how it differs from Javascript)

After learning about variable scope, the scope chain and name space in Javascript, I just wanted to sum up succinctly and briefly my understanding of PHP Variable Scope and how it differs from Javascript for those who might be wondering or learning about the topic.

The main difference between Javascript and PHP variable scope is concerning their accessibility inside and outside of functions:

  • Javascript: Global variables are visible inside functions.  There is an outer reference feature built in the engine that allows for variables in the outer environment to be visible and available in the execution context of a function.
  • PHP: Global variables do not have scope inside functions (unless you use the keyword ‘global‘ preceding the global variable being referenced inside the function to access them).  Variables inside functions, conversely, do not have global scope and are not visible outside of their parent function (you can declare a variable inside a function as global by again using the keyword ‘global‘.)

There is an excellent post on Stackoverflow here discussing variable scope in PHP in great detail.

A key ‘quirk’ to note that might be confusing is to understand that, in PHP, if a variable inside a function is created and declared as global without having existed as a global beforehand, then it’s value will only be retained inside that function, and outside of the function it will be empty.  If the global variable has already been declared in the global space, then referencing it inside a function with the ‘global‘ keyword will allow you to assign it a value that sticks globally.

I didn’t realize how simple variable scope in PHP was.  It probably helps that I already understand variable scope in Javascript fairly well, which is more complex involving Closures, Execution Contexts and the Execution Stack, so getting the gist of it in PHP is more straight-forward in comparison.

Be sure to check out my GitHub page to see what I’m working on currently.  I’m pushing a lot of code and updates and am working feverishly to make progress.  Anyways, I hope this little article helped boil down variable scope in PHP and some of the differences between it and that of Javascript.

 

 

A Key Concept in understanding conditionals: They evaluate to a Boolean.

Something that I’ve learned that has proven to be fundamental in understanding and using conditional statements in Javascript (if, while, etc.) is how and what they evaluate to.  A couple of great articles that explain this in detail are located here and here.  Both are a great read and the articles address and explain the concepts of ‘truthy’ and ‘falsey’, which I have found to be key concepts in using conditionals correctly and effectively.

Basically, conditional statements return a value and then evaluate that to a Boolean equivalent – true or false.  The equivalent numeric value of true would be 1 and 0 would be false (the way I remember this is that it’s like converting the Booleans to binary code which is a computer’s native language).

Something that has confused me lately is this example:

var x = "cat";
if (x > 0) {
alert(x);
}

Before my understanding of how conditionals evaluate, I would have looked at this conditional and read it as: “If ‘cat’ is greater than 0, then execute the code. ”   This would be confusing as ‘cat’ is a string data type and not numeric, so the condition doesn’t seem to make any sense.

But, if one has an understanding that the condition returns a result that evaluates to the equivalent of a Boolean, which has a numeric equivalent (0 or 1), and takes into account coercion in the JS engine, then the code could be understood as:  The condition (x = "cat") returns a value that is a string, and is ‘truthy’ since a string is a primitive data type that converts to a Boolean value of true, or the numeric value of 1.  So, since x holds a value that has the Boolean numeric equivalent of 1, the condition is true, and with this concept being understood, "cat" is indeed greater than 0.  The code will execute…or will it?

On testing this code in the console using Javascript, it did not execute and the condition evaluated to false.  This may be because of a feature (some would call it a ‘quirk’) in Javascript called type coercion which will convert values in an expression if their type is not relevant to the operator’s functionality.  For example, if you are using the + operator for arithmetic, and have one string and one number on either side, Javascript will attempt to coerce the type of the string to a number value.  So, if I console.log(x) after it has been assigned, then it does return a value of true when coerced to a Boolean, which would make it equal to 1.  But, because of type coercion, when “cat” is used with >, Javascript cannot coerce the string "cat" to a number type and so returns a result of NaN (Not a Number), which converts to the boolean false.   So, the expressions in if conditionals, when used in Javascript, need to be composed in a manner that keeps type coercion in mind.

The concept of conditions evaluating to a boolean for if statements (though, not the concept of type conversion) can also be applied in PHP conditionals.  Take the following example:

if ($username && $password) {
echo "Username and Password is set."
}

Without understanding that conditionals evaluate to a Boolean, and the concepts of truthy and falsey, then you would look at this and wonder what the condition is – only a couple variables are listed…what about those variables?  If you understand that the condition is evaluated to true or false, and that a variable is truthy if it ‘exists’ (i.e. is not falsey with a value of ‘not undefined, null, NaN, 0, or false’, and in this case especially, an empty string), then the code will execute.  If the variables are falsey and are an empty string or one of the falsey values listed above, then the code will not run and the user will know that the password and username variables are not set (they are falsey and the condition is evaluated to false).  I think of it like the variable has life in it and exists if it holds a truthy value, and is dead or doesn’t ‘exist’ if it holds a falsey value.  Existence is a key concept also discussed further in the helpful articles mentioned at the top of this post.

I have found that understanding that conditionals evaluate to a Boolean is crucial to understanding various uses of them.  The article mentioned at the beginning of this post does a great job of explaining the concept more thoroughly and I encourage readers to check it out if the above explanation isn’t clear.  Hope this helps out some in any case.