Object Oriented JavaScript Programming

I am trying to learn OOP with JavaScript before I start trying to learn backbone.js.

I want to be able to bind data, but I cannot get it to work.

I just made a simple protoype of a budget website that you can add to the budget and indicate how much you spent, and it will show if you have switched.

function BudgetItem(spent, budget){ this.setSpent = function(spent){ this.spent = spent; } this.setBudget = function(budget){ this.budget = budget; } this.getSpent = function(){ return this.spent; } this.getBudget = function(){ return this.budget; } } function BudgetType(type){ this.getType = function(){ return type; } } BudgetType.prototype = new BudgetItem(); $(document).ready(function(){ var food = new BudgetType('food'); $('.budget').html(food.getBudget()); $('.editbudget').change(function(){ food.setBudget($('.editbudget').data()) }); }) 

This is my code so far. I am not sure that I am doing it right. Should I distribute things? Also, can someone explain how to dynamically link data without a library?

+4
source share
2 answers
First I will give you some theory. The Javascript function is a dynamic object similar to Object . It has properties and methods and can be added at runtime (hence dynamic). This keyword is tied to a newly created object, and therefore what you do above actually creates new properties on the fly when you first pass your values ​​... which is good, but not entirely clear to another reader.

Each object and function created by the user has a link to a "hidden" Prototype object. This is an anonymous object (not accessible by name) created by the JavaScript runtime, and is passed as a reference to the user object through the prototype property. The Prototype object also has a reference to the user object through its constructor property. Combining all this together, you can now consider functions as class constructors that are created for you for each function that you have, and which can be accessed through the function prototype property. Thus, you can add fields to the Prototype object directly like this:

 function BudgetItem(spent) { this.spent = spent } BudgetItem.prototype.spent = 0; BudgetItem.prototype.setSpent = function(spent) { this.spent = spent }; BudgetItem.prototype.getSpent = function(){ return this.spent }; 

Another problem is inheriting and passing parameters to the constructor. Again, your version is valid, but you lose the ability to transfer spent and budget values ​​when initializing BudgetType. What would I do, forget the prototypes and go:

 function BudgetType(type, spent) { var instance = new BudgetItem(spent); instance.type = type; return instance; } 

This is close to what Scott Soyet suggested, but more powerful. Now you can pass both parameters (and more) and have a more complex inheritance tree.

Finally, you can create private (or pseudo-private, more accuretly) properties by providing the getter with an otherwise automatic variable (which is passed as an argument or initialized inside a function). This is a feature of the language, and it works like this:

 function BudgetType(type, spent) { var instance = new BudgetItem(spent); instance.getType = function() { return type; } return instance; } 

Now you can access the "type" passed in the constructor, obj.getType (), but cannot override the initial value. Even if you define obj.type = 'New Value', getType () will return the original parameter passed as it has a link to another context that was created when the object was initialized and was not released due to closure.

Hope this helps ...

+5
source

If you want all instances of objects to refer to the same elements / values, you can use closure:

 // create a constrctor for you object wrapped in a closure myCon = (function() { // define shared members up here var mySharedObj = new function () { this.member = "a"; }(); // return the actual constructor return function () { this.mySharedObj = mySharedObj; } }()); // create two instances of the object var a = new myCon(); var b = new myCon(); // Altering the shared object from one a.mySharedObj.member = "b"; // Alters it for all console.log(b.mySharedObj.member); 





If you want to create objects from other objects (for example, other languages ​​of the class whatever extends baseClass ), but do not want them to share values ​​by reference (instead of a clone of values), you can use something like the following:

 Object.prototype.extendsUpon = (function (_prop, _args) { return function (base) { for (var key in base) { if (_prop.call(base, key)) { this[key] = base[key]; } } function con(child){ this.constructor = child; } con.prototype = base.prototype; this.prototype = new con(this); this.__base__ = base.prototype; var args = _args.call(arguments); args.shift(); base.constructor.apply(this, args); } }(Object.prototype.hasOwnProperty, Array.prototype.slice)); 


Then to create objects ontop objects:

 // Base Object Constructor function Fruit(name) { this.fruitname = name; } Fruit.prototype.yum = function() { return "I had an " + this.fruitname; } // Object constructor that derives from the Base Object function Favorite() { // Derive this object from a specified base object: // @arg0 -> Object Constructor to use as base // @arg1+ -> arguments passed to the BaseObject constructor this.extendsUpon(Fruit, "apple"); // From here proceed as usual // To access members from the base object that have been over-written, // use "this.__base__.MEMBER.apply(this, arguments)" } Favorite.prototype.yum = function() { return this.__base__.yum.apply(this) + " and it was my favorite"; } var mmm = new Favorite(); // Outputs: "I had an apple and it was my favorite" mmm.yum(); 
+1
source

Source: https://habr.com/ru/post/1445762/


All Articles