Java developers were used to creating objects like
newis one way to construct objects. It is an operator. An empty object is created and then it invokes the function. When we use the
this is pointing to the new empty object that the JS engine creates. Then the properties are being added to that object. And as long as the function doesn’t return a value, the new object will be returned. If we wanted to create many people, we could use parameters to dynamically set firstname, lastname properties.
Function constructors: A normal function that is used to construct objects.
What about setting the prototypes?
Every function has a prototype property. It starts as an empty object. When you use the new keyword with function constructors, the proto points to the prototype property of the function constructor. So if we want to give access to all of our new objects created, we could add a method to the
person.prototype and all objects created from that function constructor will have access to those methods.
Why put methods on prototypes and not directly in the object? We could do that, but remember that objects take memory. If we have a thousand new objects then that’s a thousand new methods being copied. Instead, if we put it on the prototype, that method is only declared once, but all the thousand new objects still have access to that method.
Remember that function constructors are just functions. If you leave out the new operator, then we’ll just call the function. By convention, we capitalize the first letter of the function constructor. That way, if we see errors, we can trace them easily by knowing that they are constructor functions.
There are new ways to create objects coming in JS, so function constructors might be going way soon.
Conceptual Aside – Built-in Function Constructors
var a = new Number (3)
If we console.log a, then we get an object because all function constructors create objects. So then these objects also have access to a variety of methods. Even though it looks like your creating a primitive, that’s not true. The JS engine can also recognize that if you have a primitive
"john" and then try to do something like
"john".length it’ll wrap your primitive in an object and allow you to run that method.
You can also enhance that JS programming language but adding your own methods to the prototype of built in function constructors. Ex: if we do something like String.prototype.somethingAwesome = alaeklfja. Then all strings will have access to this new method. Libraries often leverage this, we just have to be careful not to overwrite something we don’t intend to.
We shouldn’t use built in function constructors for primitives, unless we have to.
So in an example like this, we may forget that new Number doesn’t actually create a primitive type and that can create problems when we check for comparisons and what not. So be aware that when you use them, you are making objects!
BTW: moment.js library is a good library for dates that helps manage some of the problems of constructors and dates. worth checking out.
Another Dangerous Aside
for in statements with arrays. Don’t do it. Although it works, we have to remember that arrays are objects. In an array, the index is actually the property name. If we use a for in statement with arrays, it’ll loop through all of the properties and methods. So if we add a method to the array.prototype, then that will also show up in the for in loop which could cause some unwanted things. Instead, just stick to the standard for loop with arr.length.
Object.create and Pure Prototypal Inheritance
The Object.create creates an object that is completely empty. The prototype points to whatever object you passed in. The way to work with objects like this, then we override or hide values we don’t want on our new object by writing those properties on the new object.
This works in newer browsers, but not all browsers support this. To make this work in other browsers, we have to use something called polyfill (code that adds features that browsers may lack). Here’s an example with Object.create
ES6 and Classes
JS doesn’t have classes, but it will just in a different way. But again, class in ES6 is still an object. So if you’re coming from other languages, they might see the word class and then interpret that as something they understand. In general, it still feels like a way to avoid prototypal inheritance that JS has. So if we’re going this deep into JS, we probably should just stick to Object.create and appreciate the way JS is.
Synatactic sugar: a different way to type something that doesn’t change how it works under the hood. Class is syntactic sugar that mimics what people think classes should be, but doesn’t change the fact that these are objects and we’re still using prototypal inheritance.