Как работает boxing unboxing в javascript
Перейти к содержимому

Как работает boxing unboxing в javascript

  • автор:

Is boxing coercion in JavaScript?

In You Don’t Know JS — the Coercion Chapter I’ve read that with coercion, you never get result that is a complex value, like an object or an array. Boxing wasn’t considered coercion in an accurate sense. How is boxing different from coercion in JavaScript behind the hood? I really can’t see any difference on the surface.

VLAZ -on strike-'s user avatar

3 Answers 3

This is largely a matter of semantics.

First, let’s define «boxing,» since the term isn’t commonly used in JavaScript (it doesn’t appear in the spec, for instance):

«Boxing» is wrapping an object around a primitive value. For instance, new Number(42) creates a Number object for the primitive number 42.

The only automatic boxing done in JavaScript is:

When you use a method on a primitive, like this:

«testing» is a primitive string, and thus doesn’t (and can’t) have methods. When the JavaScript engine sees a property accessor operation with a primitive root, per spec it creates a wrapper object for that primitive (a String object for a primitive string, for instance) before retrieving the property. If the property is being called (e.g., «foo».toUpperCase() ), in loose mode the wrapper object is this within the call (in strict mode it’s the primitive string). Unless something within the method call retains the wrapper object, it’s thrown away afterward.

When you use a primitive as the first argument to Function#call or Function#apply in loose mode, it’s boxed in order to be this during the call. (In strict mode, this can be a primitive.) Unless the function being called retains a reference to the wrapper object, it’s thrown away when the call is done.

Unboxing is, of course, the converse: Getting the primitive from the boxing object.

The language in the specification calls boxing «conversion»:

The abstract operation ToObject converts argument to a value of type Object.

However, it calls unboxing both «conversion» and «coercion»:

The abstract operation ToPrimitive converts its input argument to a non-Object type

A Boolean object can be coerced to a Boolean value.

A String object can be coerced to a String value.

At the end of the day, what matters is that we understand what happens when. I suspect that a strong distinction between convert and coerce has not intentionally been made by the authors.

Boxing and unboxing (wrapper objects) — JS: Introduction to Object Oriented Programming (OOP)

Methods are functions stored in object properties. If this is the case, then why does this code works:

From this code, one might draw the erroneous conclusion that a string is also an object, but that's not the case. In JavaScript, strings, logical values, null, and numbers are implemented as primitive values with no methods. On the other hand, each such type has its own constructor that boxes the primitive type with a wrapper object:

JavaScript automatically boxes primitives into relevant objects when it encounters method calls on them (and then automatically unboxes them). In other words, all the methods we call on strings the String constructor prototype contains. The same goes for all other types:

What's interesting is how the unboxing happens. To do this, JavaScript automatically calls valueOf() :

Unlike boxing, unboxing is performed for absolutely all objects. This allows you to define valueOf() yourself:

Various libraries like moment.js use this to convert the date (as an object) into a value (timestamp):

Sign up

Programming courses for beginners and experienced developers. Start training for free

Unboxing JavaScript

We all have that model in our mind that a variable is a box containing some value e.g. let a contains 10.

Let me ask you a simple question. What is a variable?

You might have answered that variable is a box in memory that holds some value and you have pictured something as below in your mind.

But is that enough? Should we leave it just here?

No, to better understand the concepts of variables, objects, reference, etc in javascript we should dig a little deep to find out how this actually works.

Look at the illustration below and try to understand what is the difference in it with respect to one above.

A variable is just a reference to a value in memory. Imagine it like a thread from one point to another. So a is not 10 but it just points to 10 in the memory.

Consider the statements below :

So does the value of a change? No, it is still the same thing just pointing to a new value. The illustration will help you to understand this better.

Now let’s move on the almighty objects in JavaScript.

Read the following example code:

Now try to imagine how this object will be stored in the memory. Hint: Try unboxing the pizza.

Done? So let’s see how this is actually represented.

Your model might look almost the same except that the ingredients object is nested inside the pizza object but this is not the case.

Objects cannot be nested in the memory so the ingredient object itself is a separate entity and is referenced by the pizza object.

But the question is why should you even care about this?

Try reading the code below and find the output of it.

Weird? Both of your pizzas are having 300g of cheese. To understand this just look at this illustration.

Remember I told you that ingredients is a separate entity and is referenced by the pizza object. So when we created the newPizza we referenced the same entity and on changing the value in newPizza changed the entity itself. But both pizzas still referenced the same ingredients object.

So how to fix this? Actually, it’s quite simple.

So rather than referencing the previous ingredients object, we created a new one that in itself is a separate entity. Have a look at the illustration below.

“ I hope that article helped you to understand how basic thing generally works under the hood and in future, you could easily unbox the JavaScript easily.

Talk about boxing and unboxing in JavaScript

In JavaScript there is a reference type called the basic wrapper type, which includes String, Number, and Boolean. How does it relate to the basic types String, Number, and Boolean? Then go to ?

The operation using the

Boxing refers to the operation of converting a basic data type to the corresponding reference type. And packing is divided into implicit packing and explicit packing.

Implicit packing

For implicit packing, let’s look at the following code:

The execution of the above code actually looks like this:

  1. Create an instance of type String;
  2. Call the specified method in the instance;
  3. Destroy this instance.

The three steps above are translated into code as follows:

Implicit packing When a value of a primitive type is read, an object of the primitive wrapper type is created in the background. Calling a method on an object of this primitive type is essentially calling a method on an object of this primitive type. The object of this basic type is temporary, it exists only at the moment of execution of the line of code that calls the method, and is destroyed immediately after the method is executed. This is why adding properties and methods to a basic type is not recognized or errors are reported, as follows:

According to packing

Another way of packing is to show packing, which makes sense. This is to show packing of a basic type using a basic packing type object, as follows:

Display boxing manipulations can add properties and methods to objects that come out of new, because instances of reference types created through the new operator remain in memory until the flow of execution leaves the current scope.

Unpacking operation

Unpacking is the opposite of packing. Unboxing refers to converting a reference type to a basic data type. This is typically done by referring to the valueOf() and toString() methods of the type.

Notice the difference between the value returned by valueOf() and toString() in the following code:

Therefore, in the process of unpacking operation, but also combined with the actual situation for unpacking, don’t blindly — thankless is very embarrassing ?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *