JavaScript: Closures

Simply put, a closure is a function in which another function, the inner function, is defined. The important part, when it comes to closures, is that the inner function remembers the environment in which it was created. What this really means is that when the inner function references the variables of the outer function, the inner function retains references to these variables even after the outer function terminates its execution and is no longer needed.

So why is this a useful feature of JavaScript, probably the most common use is as a ‘hack’ to create private state (variables) specific to a function and which can only be altered by the function that maintains a reference to that state. If you are familiar with C# or Java this can be compared to what is called encapsulation, where an object has state (variables) within it which only it can modify.

'use strict';

// Closures
//  9. Closures: Functions can be declared inside of other Functions
//     the Function has access to its own Parameters and Scope
//     but it also has access to the Parameters and Scope of the
//     Functions it is nested within
function encapsulator (param){
    var variable_in_scope = "I am in the Encapsulator.";

    function inner_function(inner_param){
        console.log("Inner Function param: " + inner_param);
        console.log("Outer Function param: " + param)
        console.log("Outer Function scope Variable: " + variable_in_scope);
    }

    try{
        console.log("Attempting to access Inner Function param from Outer Function: " + inner_param);
    }catch(error){
        console.log("ERROR: You cannot access the scope of an Inner Function: " + error.message);
    }

    inner_function("You are entering the Inner Function");
}

encapsulator("You are calling the Outer Function");

JavaScript: Numbers

One thing I love about JavaScript is the fact that it has one numerical data type for holding numbers and its called simply Number. Internally, Number represents a 64-bit floating point thatĀ holdsĀ all possible number values one might need. By having a single numerical data type, JavaScript avoids common programming problems such as type conversion errors, loss of accuracy, and overflow problems.

'use strict';

// JavaScript has a single type to hold all numbers
//  1. Number: is internally represented as a 64-bit floating point
//  2. No separation of an Integer type => 1 === 1.0
//  3. Reduces number type errors
//  4. Completely avoids overflow problems in short integers
function compareNumbers() {
    return 1 === 1.0 ? '1 equals 1, no doubt about it' : 'Um, that\'s not supposed to happen.';
}
console.log(compareNumbers());

// Crazy number operations can return strange results
//  1. NaN => is a number value that is the result of an operation that cannot produce a normal result
//  2. NaN => is not equal to any value, including itself
//  3. You can only detect NaN using the function: isNaN(number)
console.log(Number.isNaN(NaN));
console.log(Number.isNaN(Number.NaN));

var nan_result = 0/0;
console.log(Number.isNaN(nan_result));
console.log(nan_result);

// Extremely large numbers
//  1. Infinity => represents all values greater than 1.79...e+308

// JavaScript has a Math object which contains methods which act on Numbers
var some_number = 12343.343;
function floor_it(some_number) {
    return Math.floor(some_number);
}
console.log(floor_it(some_number));

// Number class Constants
var biggestNum = Number.MAX_VALUE;
var smallestNum = Number.MIN_VALUE;
var infiniteNum = Number.POSITIVE_INFINITY;
var negInfiniteNum = Number.NEGATIVE_INFINITY;
var notANum = Number.NaN;

JavaScript: Strings

If you are familiar with other programming languages, such as C# and Java, JavaScript strings should be a walk in the park as the are extremely similar (see example code below).

'use strict';

// JavaScript Strings are immutable
//  1. Once created they cannot be changed
//  2. Two Strings can be concatenated using the + operator
//  3. the '\' forward slash is the escape character to allow restricted characters

var string_one = "Some string with an escape character\" so that a paren can be in the string ";
var string_two = 'Another string using single quotes with an \' escaped single quoted';
var combined_string = string_one + string_two;

console.log(string_one);
console.log(string_two);
console.log(combined_string);

JavaScript: All About Functions

First Class Objects

Functions within the JavaScript (JS) language are saidĀ to be “First Class Objects”, this means they are comparable to objects composed from classes in C# or Java. The difference however is that classes (object templates) do not exist in the JSĀ language. Instead, JSĀ objects are created through the replication of already existing prototype objects provided by the language, but this is a topic for another day. Unlike C# and Java objects, JSĀ functions can accept parameters and contain executable code, when invoked that code can then be executed. This executable behavior is similar to methods in C# or Java, the only difference is C# or Java methods must exist within an object.

Named &Ā Anonymous

Another feature of JS functions is that they can be either named or anonymous. Named functions receive a name by which they can be referenced at the time they are defined. Anonymous Functions on the other hand are not provided names in their definitions, instead they are assigned to a variable and referenced in that manner throughout aĀ script.

"use strict";

// JavaScript Functions: First Class Objects
//  1. All functions in JavaScript are first class Objects
//     they do not have to exist inside an object
//  2. Functions all have Function.prototype as their Prototype Object
//  3. Unlike other Objects in JavaScript, Functions can be invoked
//  4. Functions can be stored in variables, objects, and arrays

// Named Function
// (referenced via the functions actual name)
function myFirstClassFunction(param){
    return "You passed me: " + param;
}
console.log(myFirstClassFunction("a Horse"));

// Anonymous Function
// (referenced via variable to which it is assigned)
var myAnonymousFunctionReference = function(param){
    return "You passed me: " + param;
};
console.log(myAnonymousFunctionReference("a Pillow"));

Passed as Arguments & Returned by Function

Because JS functions are objects and can be referenced they can also be passed around by reference. This means that JavaScript allows functions to be passed around a script as parameters to other functions to be used and executed by the receivingĀ function’s executable code. Also, functions can be defined and set up by a ‘parent’ function and returned by that function as its result of execution. The passing of functions asĀ arguments and the ability to return them is a feature of JavaScript that is not found in C# or Java. The closest thing to this in either language is a delegate, which is a special class that represents a method and can therefore be passed around.

'use strict';

// Passed as Arguments & Returned by Function
//  5. Can be passed as arguments to other Functions
//  6. Can be returned from other Functions
function iAcceptFunctionsAsParameters(param, func){
    return func(param);
}
console.log(iAcceptFunctionsAsParameters("a Bus", cool_function));


function iReturnFunctions(){
    return function (param){
        return "You passed me: " + param;
    };
}
// Obtaining reference to returned function
var returnedFunctionReference = iReturnFunctions();
console.log(returnedFunctionReference("a Bird"));

State &Ā Behavior

In conjunction, JS functionsĀ can also have their own state (variables, data) as well as behaviorĀ (methods) to support their execution or to provide additional functionality specific to the owning function. This is very similar to C# and Java objects that receive variables and methods from the class definition from which they were created.

'use strict';

// State & Behavior
//  7. Functions are Objects and can therefore have Variables & Methods (functions) of their own
var functionWithStateBehavior = function(){
    return "I am the core functionality";
};

// Add a variable to the function
functionWithStateBehavior.state = "I am a variable property on the 'functionWithStateBehavior' function.";

// Add a method to the function
functionWithStateBehavior.behaviorMethod = function(){
    return "I am the extra Method on a Function";
};

console.log(functionWithStateBehavior());
console.log(functionWithStateBehavior.state);
console.log(functionWithStateBehavior.behaviorMethod());

Stop a PostBack using JavaScript and the OnClientClick event

If you need to be able to update the text displayed in an ASP.net control such as a LinkButton through code-behind before the page is rendered but will end up using that control to invoke client-side javascript and don’t want a PostBack to happen you can simply add “return false;” after your custom JavaScript calls in the OnClientClick event handler of the control. “return false;” actually stops the page from posting back to the server and allows your custom JavaScript to be run client-side.

Example:
<asp:LinkButton ID="lbtnVisit" runat="server" Text="Ā» Default Text" OnClientClick="CustomScriptMethod(); return false;">

ASP.net: User Control Specific CSS/JS Loading

(Update: the BaseUserControl class has been updated to handle loading specific CSS or JS files or one or the other. This allows a common CSS or JS file to be passed for a set of controls making up a module within your application.)

(Update: The BaseUserControl class has been updated to handle instances where your UserControl is loaded multiple times on the same page. This will stop the CSS and JS from being loaded multiple times for each control.)

(Update: If your pages are using MasterPages for their designs make sure you add a runat=”server” to the head tag of your master pages. If you do not the Header property of the page will be null. )

In ASP.net we run into an issue when it comes our User Controls and their corresponding CSS loading in the main CSS files even when that User Control is not included in the 90% of the pages a user calls. (this is the same with JavaScript files)

In order to make sure that my User Control’s CSS is not unnecessarily loaded in the application’s main CSS file and to maintain a little more order in my design I like to use a little programming magic. This magic allows me to only load the CSS for a User Control when it is included in a page or another User Control.

To accomplish this magic I create a Base User Control from which all my User Controls inherit. This base control contains a method called LoadResources which does the following:

  1. Pulls the name of the Current Control making the call.
  2. Adds a Link tag with the path to the CSS file for the current control
  3. Adds a Script tag with the path to the JavaScript file for the current control

(All of the above are based on the CSS and JavaScript files having the same name as the control and those files being located in the same location as the current control.)

Code:

public class BaseUserControl : UserControl

{

Ā Ā Ā  #region Private Fields

Ā Ā Ā  private string _controlName;

Ā Ā Ā  #endregion

Ā Ā Ā  #region Protected Methods

Ā Ā Ā  /// 

Ā Ā Ā  /// Used if the control has custom CSS or Javascript

Ā Ā Ā  /// which needs to be loaded with the control.

Ā Ā Ā  /// The resources consist of a .css and .js files 

Ā Ā Ā  /// which have the same name as the control. This method

Ā Ā Ā  /// will search the control's location for those 2

Ā Ā Ā  /// files and add them as CSS and Javascript links to

Ā Ā Ā  /// the control's ascx content.

Ā Ā Ā  /// 

Ā Ā Ā  protected void LoadResources()

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  PullControlName();

Ā Ā Ā  Ā Ā Ā  LoadCssFile();

Ā Ā Ā  Ā Ā Ā  LoadJsFile();

Ā Ā Ā  }

Ā Ā Ā  /// 

Ā Ā Ā  /// Loads the resources.

Ā Ā Ā  /// 

Ā Ā Ā  /// Name of the file.

Ā Ā Ā  /// Type of the file.

Ā Ā Ā  protected void LoadResources(string fileName, FileType fileType)

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  switch (fileType)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  case FileType.Script:

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  LoadJsFile(fileName);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  break;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  case FileType.Style:

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  LoadCssFile(fileName);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  break;

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  /// 

Ā Ā Ā  /// Loads the resources.

Ā Ā Ā  /// 

Ā Ā Ā  /// 
styleFileName">
Name of the style file.

Ā Ā Ā  /// 
scriptFileName">
Name of the script file.

Ā Ā Ā  protected void LoadResources(string styleFileName, string scriptFileName)

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  LoadCssFile(styleFileName);

Ā Ā Ā  Ā Ā Ā  LoadJsFile(scriptFileName);

Ā Ā Ā  }

Ā Ā Ā  #endregion

Ā Ā Ā  #region Private Methods

Ā Ā Ā  private void PullControlName()

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  string controlType = GetType().ToString();

Ā Ā Ā  Ā Ā Ā  List<string> controlParts = controlType.Split('_').ToList();

Ā Ā Ā  Ā Ā Ā  if (controlParts.Count > 0)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (!string.IsNullOrEmpty(controlParts[controlParts.Count - 2]))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  _controlName = controlParts[controlParts.Count - 2];

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  private void LoadCssFile()

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  try

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  // Injects the CSS for this control into the page header

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string cssUrl = ResolveUrl(_controlName + ".css");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string cssPath = cssUrl.Remove(0, 1).Replace('/', '\\');

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (File.Exists(Request.PhysicalApplicationPath + cssPath))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string controlId = _controlName + "Style";

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (!DoesControlExist(controlId))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  HtmlLink css = new HtmlLink();

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.ID = controlId;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Href = cssUrl;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Attributes.Add("rel", "stylesheet");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Attributes.Add("type", "text/css");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Page.Header.Controls.Add(css);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  catch (Exception ex)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  //TODO: Handle exception as a warning

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  private void LoadCssFile(string fileName)

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  try

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  // Injects the CSS for this control into the page header

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string cssUrl = ResolveUrl(fileName);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string cssPath = cssUrl.Remove(0, 1).Replace('/', '\\');

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (File.Exists(Request.PhysicalApplicationPath + cssPath))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string controlId = fileName + "Style";

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (!DoesControlExist(controlId))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  HtmlLink css = new HtmlLink();

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.ID = controlId;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Href = cssUrl;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Attributes.Add("rel", "stylesheet");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  css.Attributes.Add("type", "text/css");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Page.Header.Controls.Add(css);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  catch (Exception ex)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  //TODO: Handle exception as a warning

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  private void LoadJsFile()

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  try

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  // Injects the JavaScript for this control into the page header

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string jsUrl = ResolveUrl(_controlName + ".js");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string jsPath = jsUrl.Remove(0, 1).Replace('/', '\\');

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (File.Exists(Request.PhysicalApplicationPath + jsPath))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string controlId = _controlName + "Script";

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (!DoesControlExist(controlId))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  HtmlGenericControl js = new HtmlGenericControl("script");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.ID = controlId;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.Attributes.Add("type", "text/javascript");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.Attributes.Add("src", jsUrl);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Page.Header.Controls.Add(js);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  catch (Exception ex)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  //TODO: Handle exception as a warning

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  private void LoadJsFile(string fileName)

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  try

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  // Injects the JavaScript for this control into the page header

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string jsUrl = ResolveUrl(fileName);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string jsPath = jsUrl.Remove(0, 1).Replace('/', '\\');

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (File.Exists(Request.PhysicalApplicationPath + jsPath))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  string controlId = fileName + "Script";

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  if (!DoesControlExist(controlId))

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  HtmlGenericControl js = new HtmlGenericControl("script");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.ID = controlId;

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.Attributes.Add("type", "text/javascript");

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  js.Attributes.Add("src", jsUrl);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Page.Header.Controls.Add(js);

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  Ā Ā Ā  catch (Exception ex)

Ā Ā Ā  Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  //TODO: Handle exception as a warning

Ā Ā Ā  Ā Ā Ā  }

Ā Ā Ā  }

Ā Ā Ā  private bool DoesControlExist(string controlId)

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  object control = Page.Header.FindControl(controlId);

Ā Ā Ā  Ā Ā Ā  if (control != null)

Ā Ā Ā  Ā Ā Ā  Ā Ā Ā  return true;

Ā Ā Ā  Ā Ā Ā  return false;

Ā Ā Ā  }

Ā Ā Ā  #endregion

Ā Ā Ā  #region Utility Classes

Ā Ā Ā  /// 

Ā Ā Ā  /// Types of files which are accepted by the 

Ā Ā Ā  /// resource loader.

Ā Ā Ā  /// 

Ā Ā Ā  public enum FileType

Ā Ā Ā  {

Ā Ā Ā  Ā Ā Ā  /// 

Ā Ā Ā  Ā Ā Ā  /// Cascading Style Sheet files

Ā Ā Ā  Ā Ā Ā  /// 

Ā Ā Ā  Ā Ā Ā  Style,

Ā Ā Ā  Ā Ā Ā  /// 

Ā Ā Ā  Ā Ā Ā  /// JavaScript files

Ā Ā Ā  Ā Ā Ā  /// 

Ā Ā Ā  Ā Ā Ā  Script

Ā Ā Ā  }

Ā Ā Ā  #endregion

}