JavaScript Reference types

Reference types represent objects in JavaScript. They are the closet things to classes. Reference values are instances of reference types.

An object is an unordered list of properties consisting of a name (always a string) and a value. When the value of a property is function, it is called a method.

It helps to think of JavaScript objects as nothing more than hash tables;

—–object——-

|name|value|

|name|value|

Objects can be created using the new operator with a constructor. A constructor is simply a function uses new to create an object. By convention, constructors in JavaScript begin with a capital letter to distinguish them from non-constructor functions. For example;

var object = new Object();

Reference types don’t store the object directly into the variable. It holds a pointer to the location in memory where the object exists. This is the primary difference between objects and primitive values. When you assign one variable to another, each variable gets a copy of the pointer and both reference the same object in memory.

var object = new Object();
var object1 = object;

—-Variable Object—-                                   Memory

|object|——|————->                Pointer1

|object1|—-|————–>                Pointer1

JavaScript is a garbage-collected language, so we don’t need to worry about memory allocations when using reference types. However, the best practice is to deference objects that are no longer required so that garbage collector can free up that memory. The best way to do so;

var object1 = new Object();
//do something
object1 = null;		//dereference

You can add or remove properties from objects; for example;

var object = new Object();
var object1 = object;
object.customProperty = “Awesome!”;
console.log(object1.customProperty);	//returns “Awesome”

The property that’s added to object variable is accessible on object1. The reason, same pointer.

Object type is one of a handful built-in reference types that JavaScript provides. The other builtin types are;

Array =  An ordered list of numerically indexed values

Date = A date and time

Error = A runtime error

Function = A function

Object = A generic object

RegExp = A regular expression

Each of these built-in reference types can be instantiated using new;

var items = new Array()
var now = new Date()
var error = new Error("something bad happend")
var func = new Function("console.log('hi');")
var object = new Object();
var re = new RegExp("\\d+");

Several built-in reference types have literal forms. A literal is a syntax that allow us to define a reference value without explicitly creating an object, using the new keyword.

Object literal

To create an object, we define the properties of new object inside braces. For example;

var book = {
name: "My favorite book",
year: 2014
};

Another format for creating the object if there are spaces in properties;

var book = {
"name": "My favorite book",
"publish year": 2014
};

When using object literal, the JavaScript engine implicitly creates a new Object(). This is true for all reference literals.

Array literal

Array literal can be defined in a similar way;

var colors = ["red","green","blue"]
console.log(colors[0])

This code is equivalent to the following;

var colors = new Array("red","green","blue")
console.log(colors[0])

Function literal

The best approach is to define functions using their literal form. Creating functions is much easier and less error prone using this literal form;

function reflect(value) {
return value;
}

We can create same function using function constructor;

var reflect = new Function("value", "return value;");

Using function constructor is typically discouraged given the challenges of maintaining, reading and debugging a string of code rather than actual code. There is no good way to debug these functions because these are not recognized by JavaScript debuggers. They are like a black box in your application.

Regular Expression literals

Regular expression literal form is;

var numbers = /\d+ /g;

Constructor equivalent is;

var numbers = new RegExp(“\\d+”, “g”);

When using RegExp constructor, patterns are passed as string. Any back-slashes need to be escaped. That’s why \d is used in literal and \\d is used in the constructor above.

Regular expression literals are preferred over the constructor form except when regular expression is being constructed dynamically from one or more strings.

Functions as an exception, there is no right or wrong way to instantiate built-in types.

Property Access

Properties are name/value pairs that are stored on an object. Properties can be accessed by dot notation or bracket notation with a string;

with dot notation;

var array = [];
array.push(12345);

with bracket notation the name of the method is enclosed in square brackets;

var array = [];
array["push"](12345)

This syntax is useful when we want to dynamically decide which property to access. For example, bracket notation allows us to use a variable instead of the string literal to specify the property to access;

var array = [];
var method = "push";
array[method](12345)

bracket notation allows you to use special characters in the property names. dot notation is easier to read and can be seen more frequently in applications.

How to identify reference types

The easiest reference type to identify is function type. Typeof operator on a function should return its type “function”.

function reflect(value) {
return value;
}
console.log(typeof reflect);		//returns “function”

On all other reference types, typeof operator returns “object”. This is not helpful. To solve this, there is another JavaScript operator, instanceof. This operator takes an object and a constructor as parameters. When the value is an instance of the type that constructor specifies, instanceof return true; otherwise, returns false.

var items = [];
var object = {}
function reflect(value) {
return value;
}
console.log(items instanceof Array);		//true
console.log(object instanceof Object);		//true
console.log(reflect instanceof Function);		//true

Every object is actually an instance of an Object because every reference type inherits from Object. The instanceof operator can identify inherited types.

console.log(items instanceof Array);		//true
console.log(items instanceof Object);		//true
console.log(object instanceof Object);		//true
console.log(object instanceof Array);		//false
console.log(reflect instanceof Function);		//true
console.log(reflect instanceof Object);		//true

How to Identify Arrays (Special Case)

Instanceof operator can identify arrays. There is an exception though. JavaScript values are passed back and forth between frames in the same web page. Each web page has its own global context i.e. its own version of Object, Array and all other built-in types. As a result, when we pass an array from one frame to another, instanceof doesn’t work because the array is actually an instance of Array from a different frame.

ECMAScript 5 introduced Array.isArray() that solves this problem.It identifies the value as an instance of Array regardless of the value’s origin.

var items = [];
console.log(Array.isArray(items));	//returns true

The Array.isArray() method is supported in most browser and in Node.js. This method doesn’t support IE 8 and earlier.

FavoriteLoadingAdd to favorites
Spread the love

Author: Shahzad Khan

Software developer / Architect