Manipulating variables with functions - STRENGTHENING THE WARRIOR'S ARSENAL - JavaScript in Plain Language (2015)

JavaScript in Plain Language (2015)

PART III: STRENGTHENING THE WARRIOR'S ARSENAL

3.3 Manipulating variables with functions

Passing data by value

Up to this point we have used input parameters to hardwire and interface that inserts data into functions. These interfaces serve as a bridge between the outer world and the inner works of a function.

Then, we realized that we don’t have to explicitly write parameters in order to input data into the function since we can program the object arguments to grab any argument we include when we call the function.

Here’s something new to keep in mind:

When we pass arguments to a function, like for example:

x(2,3);

The input parameters of the function make a copy of the data. They don’t really use the same data we write as arguments. This is because the function call resides on a separate memory area than the function itself. Later, if you read volume two you will see that this area of memory where we call functions or assign strings or numbers, is called the stack, and functions (as well as all other objects) reside in another area called the heap. There is no connection between these two areas. Hence the reason why the data is copied or facsimiled.

When we copy data, we are adding values to memory. This type of passing data from one mechanism to another is called passing by value, or by adding more value to memory sort of speaking.

Another common data transfer done by value is when we assign a string or numerical variable to another variable. As you know from an earlier chapter, primitive variables (those holding strings or numbers) keep the value in their own memory location. Take for example the following variables:

var x = 33;

var y = x;

x holds 33 and y also holds 33. But these are different 33 values. Data has been passed by value because we added new data into memory.

Passing data by reference

Complex values such as functions, arrays and objects, reside in the heap while the variable that points to them resides in the stack. Unlike simple values, these values and their variables are two separate entities.

Because they are two separate entities, when we assign a variable pointing to a complex data structure to another variable, the values are not copied and therefore this exchange is not passed by value. The only thing we are doing is to assign the reference or passing by reference so that both variables now point at the same value:

Take for example the array a:

var a = [1,2,3,4];

Now assign the same variable to another variable:

var b = a;

We do not duplicate the contents of the array, function or object. We now have two variables pointing at the same data. Remember the balloon with three strings z, a, b?

So when we edit a value in array a, we are in fact also changing the value of array b, or vice versa since they both point to the same array.

That is called passing data by reference. There is no duplication; these variables just refer to the same data. If we delete one of the variables or assign it to something else, the data remains untouched because there is another variable holding it in place like it happened with the balloon.

Functions are closed- in structures

In JavaScript, a function is the only data structure able to protect its data from the outer world.

What does that mean?

It means that if we declare a variable inside of a function, it can’t be seen from the global scope (outside of the function).

The global scope is in itself an inner scope if we compare it to outer worlds, like for example another webpage on a different tab. Everything we do on a web page is done under the window object which wraps the whole page. This has nothing to do with the name Windows from Microsoft.window here refers to the browser displaying of a page, the shell, and it is called window in any computer system.

The window object is, as far as a web page is concerned, the outer world or the global scope of the page. Anything declared under the window object is a property or method of the object window.

We could actually think of the window object as a function that creates everything else inside it.

When we declare a variable, like for example

var x = 33;

We are creating this variable in the global scope, which means that the parent of variable x is object window. To call this variable, we write:

x;

And it displays 33. But we could also call it like in the following example and it would work the same:

window.x;

By using dot syntax we are making sure we call the correct variable x, not some other x from the outer galaxies. For the most part window is understood and we don’t have to write it down, as we have seen throughout the book.

And what are those different galaxies? You might ask.

Remember when I said that we could think of the window object as a big function that holds all the web page functionality inside of itself and it protects it from other webpages?

Well, I didn’t put it quite like that but it serves the purpose which is to say that every function acts as a protective parent for its own data. In JavaScript functions are closed in data structures.

We could actually declare another variable x inside of a function because JavaScript will accept it without conflict, even knowing that there is another x declared as a global variable. This is because the global scope does not see the inner x from the function.

However, the function can see the outer variable x. That’s right! Functions have access to global variables because functions are their siblings. A function can see the outer variable world, but the outer world cannot see what’s inside of a function. The siblings of a function can see the function, but they cannot see what is inside of the function. The good news is that JavaScript always picks the closest identifier called upon. I mean, if we would call x from within the function, JavaScript would grab the first x that sees which is the one inside of the function. So, even if there was another x outside of the function and knowing that the function has access to it, the inner x would be JavaScript’s first choice if we ever addressed x from within the function.

For example:

var x = 33;
var test = function(){
var x = 5;
return x;
};

Call function test:
test();

It returns 5.

So, how would we address the outer x from inside of the function if we wanted to use its value in the function?

window.x would come to mind.

We will see next how to access the global x from within the function.

This” as an object placeholder

What if we wanted to return the outer variable x, instead of the inner x like we did on the previous example?

In that case we would have to use dot syntax to address the global x:

var x = 33;
var test = function(){
var x = 5;
return window.x;
};

test();

Now it returns 33, which is the outer x, not the inner x which is 5. That’s because window.x addresses the global variable x which is a child of object window.

Because JavaScript is very dynamic and also because we should write code as portable as possible (one that could apply to any object, not just the window object), programmers have come up with a generic placeholder to properly address the object currently calling the variable.

This placeholder is the word this.

If we substitute the expression window.x for this.x,
at the time of execution JavaScript will search for the object owning the property being called upon, and substitutes the placeholder this for the correct name, which in our case is object window.

But you might ask, isn’t function test also an object and if so, isn’t the owner of this.x the function itself, instead of object window?

Not really (but it is a great question). Who is the owner of the act of calling function test()?
Ans: The object window owns the command test().

Now if function test(){} was a method inside of some other object, then this would no longer represent window, it would represent the other object.

Just as an example please look at this sample script:

var x = 33;
var myObject = {
x: 7,
test: function() {
var x = 5;
return this.x;
}
};

There, we have a global x with the value of 33, another x with the value of 7 that belongs to myObject , and another x with the value of 5 inside of the function belonging to myObject.

When we call the method test():

myObject.test();

It prints out 7 which is the second x, the one that belongs to myObject. window is no longer the immediate owner of this.x because myObject is.

I have underlined earlier that this gets assigned “at the time of execution”, not only because the substitution happens at the time of execution and not any earlier, but also because the object owning the property may change from the time the property was declared to the time the property is being called upon. JavaScript is a dynamic language and we need to be careful with our assumption of what is going to happen dynamically. We will see ownership confusion happening and how to tackle each situation as we code more advanced scripts ( for more of that please readJavaScript Objects Functions and Arrays Explained).

Here’s the original function written in a more portable format where this replaces window:

var x = 33;
var test = function(){
var x = 5;
return this.x;
};

test(); (It returns 33 instead of 5).