Advanced Object in JavaScript
JavaScript is actually a prototype-based object-oriented programming language. As a result, in some cases, many things in JavaScript are a bit different from other OOP (Object-Oriented Programming) languages.
In JavaScript, almost everything is an object, except for some, which are called primitive data types. Based on this, there are generally two types of data types in JavaScript:
1. Primitive Data Type
2. Object
**1. Primitive Data Type:** In JavaScript, there are very few primitive data types, such as number, string, boolean, undefined, and null. Although these can also be treated as objects or have object counterparts, we’ll discuss this later.
**2. Object:** Except for the primitive data types mentioned above, everything else in JavaScript is an object, such as array, function, object, date, number, string, boolean wrappers, etc.
The main difference between primitive data types and objects lies in their value storage system. Primitive data types store values directly, whereas objects usually do not store data directly but rather hold a reference to the data stored elsewhere.
When we pass primitive type data as parameters/arguments to a function, it always sends a copy of the data, not the data itself. Here’s a common example to help understand this. Below is a simple program where we pass two values to a function to swap their values, meaning the value of `a` will go to `b`, and the value of `b` will go to `a`:
“`javascript
var a = 10, b = 20;
console.log(“Before swap: Value of a: ” + a + ” and value of b: ” + b);
function swap(a, b) {
console.log(“Before Swap inside function: Value of a: ” + a + ” and value of b: ” + b);
var temp = a;
a = b;
b = temp;
console.log(“After Swap inside function: Value of a: ” + a + ” and value of b: ” + b);
}
swap(a, b);
console.log(“After swap: Value of a: ” + a + ” and value of b: ” + b);
“`
When you run this program, you’ll see that `a` and `b` swap inside the function, but there is no effect on the outer `a` and `b`:
“`
Before swap: Value of a: 10 and value of b: 20
Before Swap inside function: Value of a: 10 and value of b: 20
After Swap inside function: Value of a: 20 and value of b: 10
After swap: Value of a: 10 and value of b: 20
“`
The reason is that we passed primitive type data as arguments, which sends a copy of the data rather than the data itself, so it has no effect on the original values.
But if we do the same thing with an object (reference data type):
“`javascript
var obj = {
a: 10,
b: 20
};
console.log(‘Before swap: Value of a: ‘ + obj.a + ‘ and value of b: ‘ + obj.b);
function swap(x) {
console.log(‘Before Swap inside function: Value of a: ‘ + x.a + ‘ and value of b: ‘ + x.b);
var temp = x.a;
x.a = x.b;
x.b = temp;
console.log(‘After Swap inside function: Value of a: ‘ + x.a + ‘ and value of b: ‘ + x.b);
}
swap(obj);
console.log(‘After swap: Value of a: ‘ + obj.a + ‘ and value of b: ‘ + obj.b);
“`
Now you’ll see that the data changes inside the function and the effect is seen outside as well. The actual `obj` data changes because `obj` is an object type data that holds a reference to the data rather than the data itself. When you pass it as an argument, you pass the reference. When you swap the data inside the function, it swaps the actual data according to the reference, so the data remains changed even after the function ends:
“`
Before swap: Value of a: 10 and value of b: 20
Before Swap inside function: Value of a: 10 and value of b: 20
After Swap inside function: Value of a: 20 and value of b: 10
After swap: Value of a: 20 and value of b: 10
“`
In object-oriented programming languages, everything is an object. Now, what is an object? An object is you; you are a complete object. You have properties like your skin color, height, country, name, job, etc., all of which provide information about you. Similarly, JavaScript objects have such properties. Fortunately, in JavaScript, you can open the console to see the properties and methods of objects. For example, let’s say we have an array:
“`javascript
var arr = [0, 1, 3, 4, 8];
“`
To know how many elements are in this array, you don’t need to count them yourself. You can ask the array because it has a property that holds this information:
“`javascript
arr.length;
“`
“`
> var arr = [0, 1, 3, 4, 8];
< undefined
> arr.length;
< 5
“`
Objects have their own properties. You might also have a mobile phone, which you can use to perform operations like communicating with someone far away or browsing the internet. Such objects also have some methods, which are functions. For example, to add an item to the array, you can use a method of the array:
“`javascript
arr.push(100);
“`
Now see that the item has been added to the array:
“`javascript
console.log(arr);
> arr.push(100);
< 6
> console.log(arr);
> (6) [0, 1, 3, 4, 8, 100]
“`
Where did this push method come from? You can open the array object to see:
“`javascript
console.dir(arr);
“`
Running this in the browser console, you’ll see the Array object. Clicking on the triangle button next to it will open the object:
“`javascript
console.dir(arr);
▼ Array (6)
0: 0
1: 1
2: 3
3: 4
4: 8
5: 100
length: 6
__proto__: Array (e)
“`
Here we see the length property, confirming that this array object has such a property. But where is the push method? To see that, you need to open the __proto__ part. There you will see many properties and methods. Looking through them, you’ll find the push method:
“`javascript
map: f map()
pop: f pop()
push: f push()
reduce: f reduce()
reduceRight: f reduceRight()
reverse: f reverse()
“`
This way, objects combine properties and methods to create a complex structure for our convenience. This is how JavaScript objects work based on the prototype property by default. We can also custom add methods or properties to this prototype property, which we will discuss later.
**Prototype Chain:**
Although JavaScript is an object-oriented programming language, it is fundamentally prototype-based. The object model of JavaScript differs from other major languages. Every JavaScript object has a prototype __proto__ object:
“`javascript
console.dir({});
> console.dir({});
▾ Object
__proto__: Object
“`
This __proto__ is called dunder proto. You’ll find it in every object:
“`javascript
var oneArr = [1, 2, 3, 4, 5];
console.dir(oneArr);
> var oneArr = [1, 2, 3, 4, 5];
console.dir(oneArr);
▾ Array (5)
0: 1
1: 2
2: 3
3: 4
4: 5
length: 5
__proto__: Array (e)
“`
When we first open the array, we see only the elements and the length property. The other methods, like push, are not there. But when we open __proto__, we see them. Going to the very bottom, you will see another __proto__. Opening it, you will find more methods.
The methods inside __proto__ come from the constructor of the desired object. For example, the constructor of our array is Array:
“`javascript
Array()
“`
Every object has a constructor, and within the constructor’s prototype, there are methods of that object. When we create an object, those methods go under our __proto__, so we can easily use them. Comparing our oneArr’s __proto__ with Array’s prototype:
“`javascript
oneArr.__proto__ === Array.prototype
< true
“`
This will return true.
Notice, initially we accessed an array’s length property easily with `arrName.length` because length was right at the beginning when we opened the array. But when we tried to access a method, like push, we had to open __proto__ to find it. This is called the prototype chain. When a method is called, it searches from the very beginning of the object, and if not found, it searches inside (in __proto__), and if not found there, it searches further inside (another __proto__) until the method or property is found.
This is how JavaScript’s object-oriented system works based on prototypes. All objects are connected in this model.
**Wrapper Functions:**
We learned that string is a primitive data type, not an object. So, a string shouldn’t have any properties or methods. Right? Let’s see:
“`
javascript
var str = ‘Hello, World!’;
str.length;
> str.length;
< 13
“`
Str is not an object; how does it have a length property? This happens because of JavaScript’s wrapper functions. JavaScript temporarily converts the string to an object whenever a method or property is accessed from it. That’s why it has access to properties or methods:
“`javascript
console.dir(str);
> console.dir(str);
▾ String [“Hello, World!”]
0: “H”
1: “e”
2: “l”
3: “l”
4: “o”
5: “,”
6: ” “
7: “W”
8: “o”
9: “r”
10: “l”
11: “d”
12: “!”
length: 13
__proto__: String
“`
This is how JavaScript’s object system works, allowing us to access properties and methods from primitive data types. This concept is not limited to strings; it works with other primitive types as well, such as boolean and number:
“`javascript
var num = 12345.7890;
num.toFixed(2);
> num.toFixed(2);
< “12345.79”
“`
Here, num is a primitive type, but calling the toFixed() method works because of JavaScript’s wrapper functions.
This was a brief overview of JavaScript objects and their unique system. In the following lessons, we’ll explore objects and their related functions in greater depth.
Post Comment