Javascript Object Types

This is a fairly general question, coming from beginners at the training stage, and I need to clarify something.

I am currently studying objects, and at the moment I am learning about inheritance. At this point in the tutorial, I learned a few different ways to create objects, but objects that use the this keyword have the most functionality:

 function Person(){ this.eyes = 2; this.ears = 2; this.arms = 2; this.hands = 2; this.feet = 2; this.legs = 2; this.species = "Homo sapien"; } 

I understand what I could use for this, but then an object like this was created:

 var person = new Object(); person.eyes = 2; person.ears = 2; person.arms = 2; person.hands = 2; person.feet = 2; person.legs = 2; person.species = "Homo sapien"; 

Because I seem to be able to do something with the first, which I cannot do with the latter, I wonder if there is any reason why I will not just use the old method all the time. Can anyone help me with this? I do not need a long detailed answer (although it would be appreciated). This is just a question that I want to get out of my head so as not to dwell on it.

+5
source share
1 answer

Foreword If you don't know what I mean by the word "prototype" below, skip down below the separator for an explanation, and then go back to the top of the answer :-)


Suppose in the first example you call Person through new :

 var person = new Person(); 

... then the only difference between this Person and the one you get with the second example is inheritance: created with the new Person gets the Person.prototype object as its base prototype.

I am wondering if there is any reason why I will not just use the old method all the time

If you don’t need to use a prototype, then using a constructor function can be overly complicated. Please note that your second form can be written more briefly:

 var person = { eyes: 2, ears: 2, arms: 2, hands: 2, feet: 2, legs: 2, species: "Homo sapien" }; 

This is called an object initializer: it creates a new object with the properties that you see in the list. Never need to use x = new Object() ; if you want a new empty object, just use x = {}; .

When an object is disposable, directly creating it is often the easiest way to create it.

The main functions of the constructor of advantages are that they are factories for objects that are fundamentally similar: they have the same set of initial properties, have the same basic prototype, etc. And the function can take arguments and use them to equip the object that it creates appropriately, perhaps performs some verification of the construction arguments, etc. That is: they centralize the initialization logic.

Design functions are not the only way to have function factories. You can also do:

 function buildPerson() { return { eyes: 2, ears: 2, arms: 2, hands: 2, feet: 2, legs: 2, species: "Homo sapien" }; } var person = buildPerson(); 

And if you want this person to have a prototype (ES5 and higher browsers):

 var personPrototype = { // ...properties for the person prototype... }; function buildPerson() { var obj = Object.create(personPrototype); obj.eyes = 2; obj.ears = 2; obj.arms = 2; obj.hands = 2; obj.feet = 2; obj.legs = 2; obj.species = "Homo sapien"; return obj; } var person = buildPerson(); 

(There is another, more detailed way to define these properties.)

JavaScript is incredibly flexible .:-)


"Prototype"

JavaScript uses prototype inheritance, which is a fancy way of saying that object A can be β€œsupported” by object B, so if you ask A for a property that it doesn't have, the JavaScript engine will look, this property exists on B. Quick practical example :

 var proto = { name: "proto name" }; var obj = Object.create(proto); // Creates an object backed by the given prototype 

Don’t worry about Object.create , now all you need to know is that it creates a new object and assigns it a basic prototype based on the object you pass to it. So obj supported by proto .

obj does not have a name property, but if we do:

 console.log(obj.name); 

... we see the "proto name" . This is because when the JavaScript engine tried to get the name value from obj , it found that obj does not have the name property, so it looked at the prototype of obj , proto . Finding it there, he used the value from proto .

This only happens when the value is received (except for some preliminary cases that we can ignore at the moment). When setting the value of a property, it is installed on the object on which you set it. So:

 var proto = { name: "proto name" }; var obj = Object.create(proto); // `obj` is backed by `proto` console.log(obj.name); // "proto name" obj.name = "obj name"; console.log(obj.name); // "obj name" 

The purpose of prototypes is reuse, so it is not surprising that an object can be the prototype of several other objects:

 var proto = { name: "proto name" }; var a = Object.create(proto); // `a` is backed by `proto` var b = Object.create(proto); // `b` is also backed by `proto` console.log(a.name); // "proto name" console.log(b.name); // "proto name" a.name = "a name"; console.log(a.name); // "a name" console.log(b.name); // "proto name" 

Prototype objects are ordinary objects; we can change them:

 var proto = { name: "proto name" }; var obj = Object.create(proto); console.log(obj.name); // "proto name" proto.name = "updated"; console.log(obj.name); // "updated" 

Since obj does not have its own name property, every time we access it, the JavaScript engine goes over and looks at its prototype.

The new operator automatically assigns a prototype to the objects it creates: it uses an object that has a property of the prototype function. So:

 function Person(name) { this.name = name; } Person.prototype.sayName = function() { console.log("My name is " + this.name); }; var p = new Person("Fred"); // Creates an object backed by Person.prototype, // then calls Person with this referring to the // object p.sayName(); // "My name is Fred"; 

Finally: since prototype objects are normal objects, they can also have prototypes:

 var rootProto = { name: "root proto name" }; var middleProto = Object.create(rootProto); middleProto.middleProp = "middle property"; var obj = Object.create(middleProto); console.log(obj.name); // "root proto name" console.log(obj.middleProp); // "middle property" 

For name the JavaScript engine looks like obj , does not see the name property and therefore looks at middleProto . It also does not see the name property, so it looks at rootProto . He finds it there, so he uses it.

Point of confusion: many people are confused by the fact that a property on constructor functions is called prototype and thinks that somehow it is a function prototype. This is not true. This is simply a normal property on function objects (functions are objects and can have properties). The peculiarity only lies in the fact that new uses it when calling a function through new . Non-functional objects do not have the prototype property, they prototype is not a normal property, this is an internal thing. You can get the prototype of an object by passing it to Object.getPrototypeOf :

 var proto = {/*...*/}; var obj = Object.create(proto); Object.getPrototypeOf(obj) === proto; // true 
+11
source

All Articles