Wrap everything that can be wrapped
Tags: javascript, tip, webdev, tutorial
Published: 2020-02-10 20:47:44

> _**Hello there,**_
> _Do you have 3-5 minutes to spare? If so, let's have a brief discussion about **Wrapper Objects** in JavaScript._

# Background
Data types in JavaScript can be grouped into two broad categories:

1. **Primitives** — _strings, numbers, booleans, symbols, `null`, `undefined`_
2. **Objects** — _anything that's not a primitive (arrays, functions, etc)_

While _primitives_ are usually simple immutable values, _objects_, on the other hand, are collections of one or more properties (each property having a name, and a value that can be of any data type).

### Let's consider strings for a moment
Strings in JavaScript can be created in two ways:

- **String Literal** — _Produces a string primitive._
```js
// String literal
const string1 = 'Hello';
const string2 = 'Hello';

console.log(string1[0]); // "H"
console.log(string2.length); // 5
console.log(typeof string1); // "string"
console.log(string1 === string2); // true
```

- **`String()` Function** — _Produces a `String` object when called as a constructor with the `new` keyword, and casts its argument to a string primitive when called without the `new` keyword._
```js
// String Constructor
const string1 = new String('Hello');
const string2 = new String('Hello');

console.log(string1[0]); // "H"
console.log(string2.length); // 5
console.log(typeof string1); // "object"
console.log(string1 === string2); // false
```

Since a string primitive (created with the string literal syntax) is not an object (as shown in the code snippets above), **how is it that we are able to access properties like `length` on it as though it is a `String` object?**

The reason is because at the time we are accessing the said property (`length`), we are already dealing with a `String` object (_wrapper object_).
&nbsp;

# Wrapper Objects

The ECMAScript language specification defines an abstract operation for accessing the value of a property from a value. If the value is not an object (e.g string primitive), then the property lookup is performed on a _**wrapper object**_ appropriate for the type of the value.

![ECMAScript GetV() abstract operation](https://dev-to-uploads.s3.amazonaws.com/i/xk5ucxrcw68z6x5xdoie.png)

Hence, whenever we try to access a property from the string literal, the JavaScript engine does the following:

- Create a one-off `String` wrapper object for the string literal
- Access the specified property on the wrapper object
- Discard the `String` wrapper object.

```js
// String primitive
const greeting = 'Hello World';

// Access and call toUpperCase() method
// Equivalent to: (new String(greeting)).toUpperCase()
console.log(greeting.toUpperCase()); // "HELLO WORLD"
```

The above behavior also applies to other primitive values like numbers, booleans and symbols. However, trying to access a property on `null` and `undefined` will throw a **TypeError**, since a wrapper object cannot be created for them.

```js
// Number primitive
const price = 12.357;

// Null primitive
const nullValue = null;

// Access and call `Number` methods
// Equivalent to: (new Number(price)).toFixed(2)
console.log(number.toFixed(2)); // 12.36

// Equivalent to: (new Number(price)).toExponential(2)
console.log(number.toExponential(2)); // 1.24e+1

// Access a property on a Null primitive
// Throws TypeError
console.log(null.length);
```

> In summary, the JavaScript engine knows how to _**wrap everything that can be wrapped**_, whenever it is required to do so.


## ❤️ Like and Share

If you found this post insightful in any way please:

- **Like** this post
- **Comment** your feedback
- **Share** with someone
- **[Follow me](https://twitter.com/gladchinda)** on Twitter