oop javascript deepcopy mixins multiple inheritance - javascript

First of all Hello to everyone, and sorry for my English.
I would still take advantage of the expertise and availability of this community.
In this period I'm studying inheritance in javascript, Crockford patterns, deepcopy shallowCopy etc.
I have also read many post in stakoverflow(here,here ecc..) but i dont hide that my my doubts are still many.
My aim was to create a kind of pseudo-multiple inheritance without using jquery or methods as objectCreate.
Pseudo because, as i have learned from reading various post, multiple inheritance in javascript does not exist.
In my script there are two "superClasses" (HomoErectus an HomoSapiens) an a "subClass" (ModernMan).
My copyProtoDeep function copies all properties of the prototypes of the superclasses in the prototype of the subClass.
This function takes an indefinite number of parameters the first will be the class that inherits from other classes specified in the function call.
To avoid shallowcopy if copyProtoDeep finds an object or an array the function clone this elements.
That said, I would like, if is possible, some answers to the following questions.
Is my code correct?
Is this type of ineritance a mixin?
Which are the negative aspects (or drawbacks) of this procedure?
The use of uber is correct?
Can i improve my code?
I understand that my questions are perhaps too many for a single post, but also a partial response will be read with pleasure.
Thanks to all in advance
<script type="text/javascript">
function copyProtoDeep() {
var len = arguments.length;
arguments[0].prototype.uber=[]
for (j = 1; j <len; j++) {
var parent = arguments[j].prototype;
var child = arguments[0].prototype;
for (var i in parent) {
if (parent.hasOwnProperty(i)) {
if (typeof parent[i] === 'object') {
child[i] = Array.isArray(parent[i]) ? parent[i].slice(0) : JSON.parse(JSON.stringify(parent[i]));
} else {
child[i] = parent[i];
}
}
}
child.uber[j] = arguments[j].prototype
}
}
function HomoErectus(name){
this.name=name
this.sayHello=function(){return 'Hello from '+this.name}
}
HomoErectus.prototype.discovery='fire'
HomoErectus.prototype.scream='yabadabadoo'
HomoErectus.prototype.friends=['wilma','Betty','Barney']
HomoErectus.prototype.uberTest1=function(){
if(this.uber){return 'the ancestor of '+this.name+" discovered "+this.uber[1].discovery}
else{return this.name+' discovered '+this.discovery}
}
function HomoSapiens(name){
this.name=name
this.iam=function(){return 'I am an Homosapiens an my name is '+this.name+' and my weapons are '+this.dangerousWeapons.w1}
}
HomoSapiens.prototype.discovery='wheel'
HomoSapiens.prototype.dangerousWeapons={w1:'bow and arrows',w2:'Spear and shield'}
HomoSapiens.prototype.uberTest2=function(){if(this.uber){return 'yes yes'}else{return 'no no'}}
function ModernMan(){
HomoErectus.apply(this, arguments);
HomoSapiens.apply(this, arguments);
}
copyProtoDeep(ModernMan, HomoErectus,HomoSapiens)
ModernMan.prototype.discovery='pc'
var fred=new HomoErectus('Fred')
console.log(fred.uberTest1())
var bubba=new HomoSapiens('Bubba')
console.log(bubba.uberTest2())
var john = new ModernMan('John')
john.friends.push('Riky')
john.dangerousWeapons.w3='guns and bombs'
console.log(john.uber[1].friends)
console.log(john.uber[2].dangerousWeapons)
console.log(john.uberTest1())
console.log(john.uberTest2())
</script>

there are my answers:
Is my code correct?
I think the mixin has no exact rules, so your code is probably right. I didn't find any bigger problem.
Is this type of ineritance a mixin?
If you inherit all methods, then the mixin is (can be) equal to multiple inheritance. And because you also called super constructor, it looks more like inheritance than mixin.
Which are the negative aspects (or drawbacks) of this procedure?
The diamond problem. You probably heard about it. Its a common problem of multiple inheritance. If HomoSapiens and HomoErectus will have same method, then according to your mixin last argument of your copyProtoDeep wins, so HomoSapiens method will be used. But it is the thing about mixins... with inheritance, it is known problem and inheritance isnt supposed to solve it. On the other side, every solution from mixin is acceptable. So if you define that last argument method will have a priority, then it is a correct solution.
The use of uber is correct?
I see one problem. What if parent is also a mixin? Then it has parent.prototype.uber, which will overwrite child.prototype.uber.
Can i improve my code?
I would try to fix the previous problem with uber. For example watch ecma-262 5.1 specification of Property Attributes. This is good thing for libs or patterns. With it you can implement uber different way, so it can't be overwritten for example.
Last words
I have to say that Im not a mixin or multiple inheritance expert. I avoid it. Im just good in javascript and rather use simple inheritance and interfaces. So this was just my point of view.

Related

What technique I'm applying to reduce code?

What kind of programming technique am I applying when I call an Object inside a Object to extend the object?
On my Job, we have a rule that no JS file may have more 50 lines. So when we have an very large Object we separate the code on new child objects but work as single Object:
function ObjetoA(parent){
parent.showMessage() = function () {
console.log('HOLA MUNDO');
}
}
function Objeto(){
new ObjectoA(this); //this one
this.sayHiAgain() = function () {
console.log('HOLA MUNDO OTRA VEZ');
}
}
let Prueba = new Objecto();
Prueba.showMessage();// it works
Let's see what's going on:
When you call Objeto(), the code new ObjetoAA(this) is run.
Now, ObjetoAA(parent) is run, which sets the property showMessage on parent. This property is a function. So now the Objecto has a function property showMessage.
I don't think there's any particular name for this pattern in the way that you've implemented it. It's just... using objects. I will say that it's an inventive way to extend/modify/split/compose a class. It's sort of simulating a mixin.
But it shouldn't be necessary: look at the gymnastics you've had to go through just to meet an arbitrary line count limit. Did it improve your productivity? Did it improve the readability and maintainability of your code? Nope.
Some limit probably makes sense: nobody wants to scan through 30,000 lines of JavaScript in a single file (at least, not the unminified version); but 50 is a very, very small limit. I recommend that you push back on this policy if you can.

What is a good example that shows the difference between OOP and procedural programming in JavaScript? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
I can't get my head around OOP in JavaScript.
Many years ago, I used to dabble in programming BASIC and learned a bit of COBOL and FORTRAN in school so I am somewhat familiar with procedural programming, but I never learned any of these to a very high level of proficiency or complexity. I've also done a few hackey things with JS but I guess it was mostly procedural in nature rather than OOP.
Recently, I've decided to train myself to become a web developer and learn JavaScript properly, and based on the rave reviews, I decided on Head First JavaScript Programming as my textbook.
The problem I am having is that I can't figure out how or why using objects is really any different or better than using functions and variables. I've looked around at a ton of tutorials and videos but they all say the exact same thing as the book. "Objects are useful because they are analogous to everyday items in real life such as a car. A car has a model year, a make, a weight, a color, etc... A car can also do things such as start, stop, go, etc. They are functions inside the object and called 'methods'." and that is followed by "this is how to create an object:"
var myCar = {
make: "Chevy";
year: 2004;
kilograms: 2000;
color: "blue";
go: function() {
alert("go!");
}
};
Great. Now I know that objects are somehow analogous to real life things and I know how to make one with properties and methods. I get that.
And I can access these property values by calling them as follows:
a = myCar.make;
b = myCar.year;
c = myCar.color;
I can also call the function (or method):
myCar.go();
Wonderful. But I STILL can't figure out WHY I want to do it this way. Why is this better than the following?
myCarMake = "Chevy";
myCarYear = 2004;
myCarKgs = 2000;
myCarColor = "blue";
function go() {
alert("go!");
};
Other than how the code is organized, I don't understand how it's any less procedural. Statements are executed in order, after all. And I don't see what the advantages are to doing all of this.
I keep thinking that what I really need in order to understand this is to see two programs that do the same thing, one coded procedurally with normal variables and functions, and the second one programmed with OO in order to see the difference and how these objects interact with each other in an advantageous way.
I find that all the textbooks and websites that I have found never explain how similar things behave differently or why one is better than the other and there are few if any examples of how to tie it all together well. Most books and tutorials just tell you what you can do but not why you'd want to do that or choose one way over an other. (Irrelevant to this question but another thing I'm wonder about is, I know I can assign a function to a variable but WHY would I want to do that?)
To be clear about what I am looking for, my question is, can someone show me a program that is programmed both ways (both do the same thing and are simple enough for a beginner but complex enough to show why OOP might be needed or advantageous) to highlight the differences and explain why it's better?
In practice, if you have a small script or application, you will not see the difference.
But once you move towards larger applications and bigger code bases, you'll see that OOP works much better than PP.
Here are some high-level advantages of the OOP approach over the PP:
1) Modularity and maintainability
The code becomes modular, the related data and methods are packaged into objects.
This makes it much easier to keep the code under control.
It is complex to see this on few lines of code, but as your code grows, the procedural code most often turns into a mess.
With OOP your code is naturally splitted into smaller parts (objects) and even as the codebase grows, it is still easy to keep the code in order.
The modularity leads to better maintainability - it is easier to modify and maintain the code.
2) Flexibility
It is much easier to replace the part of the code with some different functionality.
For example, you can have the Logger object which writes logs to files. But then you decide to write logs to the database instead.
With PP approach you would need to go over the whole code base searching for something like log_to_file(message, file_name) and replace with something like log_to_db(message, db, table_name).
With OOP you just create the new DbLogger and "plug it" into the system instead of the previous file logger, so the code which logs data will still look the same, like logger->log(message). Even better, you can decide on the type of the logger run-time, for example, read the setting from the configuration file and create whether file logger or db logger.
3) Testability
With OOP it is much easier to take our part of the code (object) and test it alone. If it depends on other objects, these can be replaced with fake implementations (test mocks), so you can really test the piece of code alone.
Just to demonstrate the difference, let's imagine that instead of one car, you now have three (also the go method should really do something with the variables, otherwise it doesn't make much sense):
var myCarMake = "Chevy";
var myCarYear = 2004;
var myCarKgs = 2000;
var myCarColor = "blue";
var yourCarMake = "Ford";
var yourCarYear = 2001;
var yourCarKgs = 1990;
var yourCarColor = "white";
var hisCarMake = "Ferrari";
var hisCarYear = 2011;
var hisCarKgs = 2990;
var hisCarColor = "red";
function go(make, year, kgs, color) {
alert(make + " " + kgs + " " + year + " " color);
};
go(myCarMake, myCarYear, myCarKgs, myCarColor);
go(yourCarMake, yourCarYear, yourCarKgs, myCarColor);
go(hisCarMake, hisCarKgs, hisCarKgs, hisCarColor);
Notice some of the properties of this code:
busness-logic code (the definition of car properties and the go method) is mixed with the client code (the part where we call go), we can not separate them, because client code refers to the global variables we created (like myCarMake)
many repetitions (like CarMake is written 6 times) and it looks messy
easy to make the error (there are errors in last two calls)
hard to maintain - if we add a new parameter for the car, we will have to go over all the code base
Now the version with object (to simplify the code, I keep it as a simple object and separate constructor function, see this for other ways to define the object):
var CarPrototype = { // empty object-prototype
make: "",
year: 0,
kilograms: 0,
color: "",
go: function() {
alert(this.make + " " + this.kgs + " " + this.year + " " this.color);
}
};
// function that constructs the new object
function createCar(make, kgs, year, color) {
var car = Object.create(CarPrototype);
car.make = make;
car.kgs = kgs;
car.year = year;
car.color = color;
return car;
}
var myCar = createCar("Chevy", 2004, 2000, "blue");
var yourCar = createCar("Ford", 2001, 1990, "white");
var hisCar = createCar("Ferrari", 2011, 2990, "red");
myCar.go();
yourCar.go();
hisCar.go();
And some properties of this code:
the business logic is clearly defined and separated from the client code, client code is not aware of internal structure of the car object
less repetitions and in general the code looks clearer
once the object is defined, it is really complex to make the error (you just do myCar->go(), no parameters passing, no chance to mix them or pass in the wrong order
easier to modify (if we add a new property for the car, the myCar.go() calls in client code don't need to be changed)
For sure, I didn't mention all the reasons to use OOP over PP, but I know this from practice - try to spend some time learning OOP principles and start using it and you'll see the huge improvement in code structure. You will make mistakes and do things wrong in the beginning, but the result will anyway be better than procedural code.
The general approach here is more important than specific language constructs, you can use same principles in C (which is not an OOP language) and in javascript (which has a specific OOP support) as well as in other languages.
I don't know a resource which compares PP and OOP side by side, but I think you don't really need it. Just look at examples of OOP applications and imagine how these would look like if written in procedural style.
My favorite book about OOP is Design Patterns, it demonstrates how elegant and powerful can be interaction between objects.
Probably, you will also need to find something where basic OOP concepts are explained (already mentioned encapsulation, polymorphism, inheritance) and principles (most notably SOLID).
Truthfully, I always found the idea of properly scoped variables a good argument for the OOP approach of javascript.
Taking your example for instance:
var myCar = {
make: "Chevy",
year: 2004,
};
var make = "Ford";
console.log(make);
console.log(myCar.make);
Yields "Ford", then "Chevy". The reason scoping can be an issue within JS is the sheer number of libraries that can be pulled in. Yes small programs tend to be easier to write using procedural. But when you are pulling in a dozen other libraries, you do not know which approach they use for declaring variables - which can lead to obscure errors.
Yes, you could just declare the variables within the function definition and they would then be scoped to just that function (example below), but then they can't easily be reused!
function go(){
var make = "chevy";
console.log(make);
};
go();
console.log(make) ///throws undefined 'error'
OOP provides an approach that is scope safe, and easy to reuse (which is great for external libraries).
They say OOP is about inheritance, polymorphism and encapsulation.
We will leave encapsulation aside, as it has nothing to do with OOP, but rather with modules. (At last, modules are the part of the language!)
Inheritance is a powerful concept that makes possible to reuse both logic and data. Extending your car example, we can do the following.
var AbstractCar = {
go: function () {
alert('go ' + this.make+ '!');
}
};
var MyCar = Object.create(AbstractCar, {
make: { value: 'Chevy', writable: true }
});
var YourCar = Object.create(AbstractCar, {
make: { value: 'Mustang', writable: true }
});
MyCar.go(); // go Chevy!
YourCar.go() // go Mustang!
Polymorphism, on the other hand, allows you to treat different kinds of objects as one, as long as they conforms to the interface. Or, in the other words, as long as they can do want we want them to do.
For example, we need a string representation for out objects. Anything, that has a toString method could be concatenated with a string.
var myCar = {
make: "Chevy",
year: 2004,
toString: function () {
return this.make + ' ' + this.year;
}
};
var statement = 'I want to sell ' + myCar;
console.log(statement); // I want to sell Chevy 2004
And that's really it.
OOP is not some superior technique that should be mastered for what its worth. Though it can pretty handy. : )

Strange javascript behaviour - error unless 'classes' are defined in correct order

I have a very strange problem with javascript and easel js.
I am using the easel.js library and am already fairly far into the construction of a project using it.
I am attempting to have a 'class' (I know they aren't technically classes in javascript but I will use this terminology for lack of a better word) inherit the Shape class from easel js, and then have another class inherit that. So it would be something like this:
easeljs.Shape --> MenuButton --> BuildingButton
The code I am using looks like this:
BuildingButton.prototype = Object.create(MenuButton.prototype);
BuildingButton.prototype.constructor = BuildingButton;
function BuildingButton(){
MenuButton.call(this);
}
MenuButton.prototype = Object.create(createjs.Shape.prototype);
MenuButton.prototype.constructor = MenuButton;
function MenuButton(){
createjs.Shape.call(this);
}
The problem is that I get the following error with this code:
Uncaught TypeError: undefined is not a function
easeljs-0.7.1.combined.js:8439
(line 8439 is pointing to the initialize() function in the Shape() constructor).
now here's the strange thing. If I change the order of the definitions so that the sub class is defined second and not first, it works fine!
MenuButton.prototype = Object.create(createjs.Shape.prototype);
MenuButton.prototype.constructor = MenuButton;
function MenuButton(){
createjs.Shape.call(this);
}
BuildingButton.prototype = Object.create(MenuButton.prototype);
BuildingButton.prototype.constructor = BuildingButton;
function BuildingButton(){
MenuButton.call(this);
}
This is very confusing as I can't seem to figure out why on earth this is happening. I could just make sure I define them in the correct order and leave it be, but I have all my 'classes' in different source files which are then strung together by grunt, which does so alphabetically.
Also, I feel like I may have a big gap in my knowledge of javascript (or maybe easel.js I'm not sure what exactly is causing this behaviour).
Thanks in advance for your help and I hope the question makes sense!
MenuButton.prototype = Object.create(createjs.Shape.prototype);
…
BuildingButton.prototype = Object.create(MenuButton.prototype);
These two statements have a clear dependency and need to be executed in the correct order (for the function declarations the order is irrelevant if placed in the same scope/file, but if in different files they need to be loaded in the correct order obviously).
I have all my 'classes' in different source files which are then strung together by grunt, which does so alphabetically
That's not a good idea. You should use some build tool/script that allows the declaration of dependencies.
Read this to clear things out: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Inheritance_and_the_prototype_chain
In first example you try to inherit from nothing, since MenuButton.prototype is not yet defined. To make it work just add MenuButton.prototype = new createjs.Shape.prototype(instead of Object.create() wich shouldn't be used anymore) to instantiate it first before you can you use it. Your first code is like you are willing to eat a banana before having one.

OOP - Is it better to call functions from within other functions, or to have one big controller?

I'm re-writing a fairly complex script that I created a few weeks ago. After showing it to a few people, they all agreed that I should break it up into smaller pieces (classes) that have a specific purpose, and SOLID object-oriented programming principles
As a self-taught programmer these concepts are pretty new to me, and I'm a little confused about how to best transfer data from one function/class to another. For instance, here is a simplified structure of what I'm building:
MY QUESTION IS:
Should I have a "controller" script that calls all of these functions/classes and passes the data around wherever necessary? Is this where I would put the for loop from the diagram above, even though it would work just as well as part of Function 1 which could then call Function 2?
Without a controller/service script you'll not be able to meet single responsibility principle in fact. Here's a high level design I'd implement if I were you.
FileRepository
Should expose a method to get a file. Let's name it GetFileById.
MongoDBRepository
Methods for CRUD operations. Such as SelectById, SelectByQuery, Update, Create, Delete.
Object creation logic
If your createNewObj logic is simple it would be enough to move it to your object contructor so that your code looks like that: var newObj = new MyObj(json[i]);
But if it's relatively complex maybe because you use some third party frameforks for validation or whatever you'd better create a factory. Then you could would look this way: var newObj = MyObjFactory.Create(json[i]);
Service/controller
Finally you'll need to implement controller/service object. Let's name it WorkService with a method DoWork which should handle all interactions between the repositories and other objects discribed above. Here's approximately DoWork should look like:
function DoWork(fileId){
var json = fileRepository.SelectById(fileId);
for(var i=0;i<json.length;i++){
var newObj = new MyObj(json[i]); // or calling factory method
var dbRecord = MongoDBRepository.SelectByQuery(newObj.name, newObj.date);
if(dbRecord){
MongoDBRepository.Update(newObj);
}
else{
MongoDBRepository.Create(newObj);
}
}
}
Please note it's just a javascript syntax pseudo-code. Your actual code might look absolutley different but it gives your a feeling of what kind of design your should have. Also I exmplicitly didn't create a repository objects inside DoWork method, think of the way to inject them so you meet Dependency inversion principle.
Hope it helps!

Compound Javascript Elements

I've got this page I'm doing some tests in Javascript and jQuery: JS Tests
I've got a few questions on how to create, not sure if this is right term, but compound controls via Javascript. In something like Flash, you'd create the Object class, have the getters and setters, draw your images, etc. In JS, it seems to be a very different thought process. My main question is How do you create multiple elements with getters and setters to be rendered, filtered, and interacted with in Javascript?
The main code regarding this example sits with:
var html = (function(){
// var FRAG = $(document.createDocumentFragment());
htmlBox = $(document.createElement("div"));
var eTitle = $(document.createElement("h4"));
var ePrice = $(document.createElement("p"));
// set class first
htmlBox.addClass("box")
htmlBox.css({
backgroundColor : color
})
// set text values
eTitle.text(title);
ePrice.text("$" + price);
htmlBox.append(eTitle)
htmlBox.append(ePrice)
return htmlBox;
})();
... inside the Box() class. If someone could take a look at the source and let me know what isn't quite right, that'd be great.
EDIT
Here's the final result for this example. Some logistics to work out, but what I'm after.
http://geerswitch.in/tests/obj/
As for the jQuery creating nodes, the built in JS version works fine for this, and some research on Google shows that the non-jquery way is faster in most cases anyway (and looks worse, imo)
You're doing it almost right. You've created a Box class to represent your higher-order UI element, you're instantiating it for each element, and your main program is manipulating the elements through its interface. The only thing you're missing is the split between the public interface and the private implementation. There's nothing to prevent me from doing myBox.price += 10 right now, even though the Box interface clearly implies that price should be set at construction and never modified.
JavaScript doesn't have visibility modifiers like "private" and "public", but you can create the same effect yourself. Check out Douglas Crockford's explanation for the details. Crockford is an opinionated genius when it comes to JavaScript, and he's the brains behind JSLint and JSON.

Categories

Resources