OO programming: should functions or object literals be used

I know a bit of Java, and I like all of these classes and the OO programming style. Well, I read about JavaScript, and I see that there is no “classic” OO style, like in Java and C ++, not even a simple constructor. The programmer has a lot of choices. Well, I did it, what do you think about it. Is it possible to code such a constructor?

//constructor of Human function Human(name, age, size, married) { this.n = name; this.a = age; this.s = size; this.m = married this.printInformation = function() { return "Name: " + this.n + ", Age: " + this.a + ", Size: " + this.s + ", Married: " + this.m; }; } var human1 = new Human("Lenny Linux", 42, "142cm", false); window.alert(human1.printInformation()); 

His work, so I think everything is in order. But there is a problem: I have other options. How to use these "object literals" or what they called. I could do this:

 var human1 = { name: "Lenny Linux", age: 42, size: "142cm", married: false, printInformation: function() { //... } } 

Well, it's faster, isn't it? And after I wrote this, there is a “object” of Man, another that I have to initialize. But I like one more. It’s easier for me to get around my code. But the first example is NOT typical JavaScript — how right? So should I forget all about Java and use a special JavaScript style? Or can I keep my style of Java code? What do you think?

PS: Another question for the first example. It drives me crazy that I cannot force a programmer if hes initializes the constructor, to use only the boolean, if hes to a "married" variable. But I really want to force him. Same thing for Age: maybe only Integer ... Any ideas?

Thanks!

+4
source share
2 answers

The two approaches that you describe are actually completely equivalent (apart from the syntax) and mostly endorsed from a Javascript point of view. Nevertheless, you probably should not choose what to do, based only on what is convenient for you now - in the long run you will need to get used to working with the language, and not against it. Moving on ...

What if I want my fields to be of a specific type, like in Java?

Javascript is dynamically typed, so it will be difficult for you to try to apply the same static typing paradigm. You can try to execute runtime checks (using typeof) during the constructor of objects, but this is usually not worth the trouble, since the verification will still be performed at runtime, but the verification will not lead to a similar error in any case, and typeof is very limited (it’s difficult to verify that something is an array, it is annoying to check the interfaces and allows you to not run in the “alien” objects of the browser ...)

In the end, it’s not very tense with the dynamic typing - you will soon get used to it.

If you said that the object literal approach and the constructor function approach return the same result, what is the difference?

First of all, while object literals are a very neat part of the syntax, there are some things that need to be divided into several statements, so you need a function for them:

 //Note: lowercase name since I won't be using 'new here... //there is a good convention for only using capital names on // "real" constructors function create_human(name, age){ var obj = {}; obj.name = name; obj.age = age; //this needs to be on a separate statement //since it involves the other fields obj.isAdult = (obj.age >= 21); return obj; } //not using 'new ...yet var that_penguin = create_human("Lenny", 42); 

Note that object literals can still be very useful here, and it is very popular to use them to provide named parameters and default parameters in cases where normal ones have large parameter lists:

 function create_human(args){ var obj; obj.name = args.name; //... } var x = create_human({ name: 'Lenny', age: 42, //... }); 

Remember:. Up to this point, using a function to create an object and an object literal is only a matter of style and organization, and the best approach usually depends on which particular case you are dealing with. In my experience, object literals are very good for creating singleons and configuration dictionaries, and functions are very useful for providing invariants in complex objects, offering a shorthand notation for general ones. p>

So, what is the deal with the “real” design functions, new and then?

The disadvantage of explicitly manipulating objects manually is that we are missing out on some of the OO kindness we are used to. Providing each object with a copy of its methods, we not only lose space (in the classical language they will be stored in the class), but we lose differential inheritance (since everything is static). The way Javascript deals with this is the prototypes. All objects have a prototype and when searching for a property (or method), it is recursively scanned in the prototype if it is not found immediately.

A common example of using prototypes is that the class of objects saves its instance variables on its own, but shares methods:

 lenny: name: "Lenny" age: 42 __proto__: Person.prototype glenda: name: "Glenda" age: 19 __proto__: Person.prototype Person.prototype: printInformation: ... tons of methods: ... 

Thus, we can access lenny.printInformation without even noticing that this method is shared with Glenda.

To create an object with a prototype, you can either use Object.create (at least for newer browsers), or in the old way using the function constructor and the new operator:

 function Person(name, age){ //The 'new operator provides an empty // 'this' object with a suitable prototype. // The constructor function just needs to fill in the // instance variables. this.name = name; this.age = age; //note: no return statement! //and no methods as well //(unless they need to be closures but thats another thing)... } //Methods in Person.prototype, will be shared by all Person instances: Person.prototype = { printInformation: function(){ console.log('my age is', this.age); } }; var lenny = new Person("Lenny", 42); 

Summarizing

Use the constructor functions and the new operator if you want to use the prototype functions of the language.

Use regular functions or object literals otherwise.

+5
source

You should read about prototypical inheritance from this book .

  //constructor of Human function Human(name, age, size, married) { this.n = name; this.a = age; this.s = size; this.m = married; this.printInformation = function() { return "Name: " + this.n + ", Age: " + this.a + ", Size: " + this.s + ", Married: " + this.m; }; } var human1 = new Human("Lenny Linux", 42, "142cm", false); window.alert(human1.printInformation()); 

So printInformation is a good candidate to cast a Human prototype to create a common method between Human instances. When you define Human , all references to this will be the object literal set to the empty object backstage. In addition, behind the scenes, a hidden _proto_ property is _proto_ object, which is literally a reference to the Human.prototype object. Therefore, until you link Human.prototype to a new object, all instances of Human will have the same pointer to Human.protoype . So, here is a standard example of what you want for efficiency.

  //constructor of Human function Human(name, age, size, married) { this.n = name; this.a = age; this.s = size; this.m = married; }; Human.prototype.printInformation = function() { return "Name: " + this.n + ", Age: " + this.a + ", Size: " + this.s + ", Married: " + this.m; }; var human1 = new Human("Lenny Linux", 42, "142cm", false); window.alert(human1.printInformation()); 

At run time, the interpreter will try to find printInformation in the instance itself and will not find it in this case. This way it will follow the _proto_ link. He finds it there because Human.prototype.printInformation is a function.

The reason this is effective is because all instances point to the same object: Human.prototype ; whereas when you say this.method = function() {} inside the constructor, each instance gets a new function assigned to it.

+1
source

All Articles