Understand the Hazards of Using Imperative Code - Is this a function or an object?

I know we don’t have to do much in this lesson, but I want to understand it completely before moving forward.

Right at the top, there’s something that confuses me: is “Window” here an object or a function? Or somehow both?

// tabs is an array of titles of each site open within the window
var Window = function(tabs) {
  this.tabs = tabs; // we keep a record of the array inside the object
};

Argument for it being a function: The “Window” variable is literally set equal to a function declaration.
Argument for it being an object: The word “Window” is capitalized, and inside the function, there is a reference to “this” – both things I haven’t seen being used in functions before.

I’m not using to seeing something that (from my point of view) blurs the lines between these two concepts. Could someone explain what’s going on here?

I believe (and someone else please correct me if I’m wrong, I’m still a nooby at this myself) that Window is a Class. I think the standard for naming them is to begin it with a capital letter and I think “this” is also used with classes.

Check out this MDN page on it: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes

2 Likes

Window is a function.
Window is capitalized out of convention: it implies that we will use the function named Window as a constructor.
A JS function is a constructor when it is used as the operand of the new operator, as in the following example.

let myNewWindow = new Window(['first tab', 'second tab']);

What this code is telling the interpreter is:

  • give me a new blank object*
  • run the function Window once with the given parameters, ['first tab', 'second tab']), and with the variable this set to point at the new object you just gave me.

As a result, in stages that you never have access to in code (all happens before the line stops executing),
myNewWindow === {} (true)
myNewWindow === { tabs: ['first tab', 'second tab'] } (true for this specific object that was returned by the new operator.

Notice: I put an asterisk in the list of steps above, because when you get to the Object-oriented Javascript section, the “blank” objects is actually a copy of the .prototype property of the function Window. It’s a little complicated, I’m trying to work on a teaching tool that simplifies it. But for right now, forget the asterisk, and everything I said above this notice is correct.

2 Likes

Thanks everybody for your responses. This is still a little over my head, but I think I’m starting to grasp it.

It seems that the main reason that Window needs to be a function here (and not just a normal object) is because it has to be able to receive and store information that isn’t known in advance (the “tabs” array), correct?

Yes, essentially. It’s not that it isn’t known in advance, the point is that it creates an instance of an object — you want the data and functionality to just be for that specific type of thing.

In languages like Java or C#, this would be a class, which are basically templates used to generate unique instances of objects. JS does not have classes* in the same sense: what it has is functions (used to define what the object will look like), and the new keyword (which is what creates the object out of thin air). You’re creating a specific type of object, rather than just any old object.

* it does have the class keyword, but JS doesn’t quite work the same way, although the end result is fairly similar.

1 Like

Based on your response, I think I see what’s still confusing you.

To clarify the terminology of what @DanCouper said, in object-oriented programming, we model real-world objects by storing relevant information about them, as in the syntax-free example below:

Car: {
  function: transportation;
  wheels: 4;
}
Bicycle: {
  function: transportation;
  wheels: 2;
}

Because these two objects have similar information (properties/component variables that are set to the same value), we can say that in our model, they belong to the same class of object. That class could be something like:

Class Vehicle {
  function: transportation;
}

which allows us to say that a Car or a Bicycle is an INSTANCE of the class of objects that are Vehicles.


In the example code I wrote in my previous reply, there are 3 objects involved, 2 of which are mentioned explicitly, and one of those 2 is an instance of the class of Function objects, as you can see if we map the variable names onto simpler names.

let myNewWindow = new Window(['first tab', 'second tab']);
let A = new B();

A is a Javascript variable, and it can hold anything. Its type is determined by what we assign to it. In this case, that would be the result of the expression new B();

B is a function. As in all math and computing, functions return values based on what their input parameters were. In this case, we pass in no parameters, but B will return a value, even undefined if no explicit return value was called, as in:

function B(){};
let testReturnValue = B();
console.log("The value returned from 'blank' function B is:");
console.log(testReturnValue); // expected output: undefined

CodePen with above code
What’s important to realize in the current discussion is that B, while being a function in the general sense of functions, is a function in Javascript. And all functions in Javascript are first-class functions, which means they can be treated like any other data (assigned as the values of variables, like the function assigned to the variable Window in the lesson example), or passed as parameters to other functions (the definition of a callback). In Javascript, such values have to be one of the seven data types: 6 primitives (number, string, boolean, null, undefined, symbol) or an Object. Since a function clearly can’t be represented by one of the 6 primitive data types, it has to be an Object. The following picture shows the relevant expanded browser console output from a slightly different pen to show Functions are Javascript objects.


Link to the pen - Note: The codepen console is insufficient to demonstrate what is necessary.

And finally, object C is not listed in the source code: let A = new B(); but this “hidden” object exists. It is the one that was copied by the new operator. In addition to copying C, new also assigned a reference to the copy as the value of this to any source code inside the Function object B, so that any code that alters this will be altering the copy. new knows which object to copy because as an object, the function B has properties (key/value pairs), and one of those properties stores a reference to the object to be copied, the prototype of all Bs. In the picture above, Firefox’s console lists this as the prototype property of the function object B. All functions have a prototype property, so all functions can be used as constructors, although by convention, we Capitalize the ones that we intend to use as Constructors.

Now, let’s summarize with specifics: A is an instance of the class of B objects. All instances of Bs are created by calling the new operator on the constructor function B, and start their lives as copies of the prototypal B object, C, which then have the commands inside the constructor function B() run upon them.

Further reading:
MDN - first class functions
MDN - “Function” constructor - the construction function that makes new functions

1 Like