I have a view which displays two different sets of data:
Let's say proposalDetails and orderDetails.
I have inherited some code that attempts to backup these two classes as members.
The problem with the code in comments below is that the class functions are not cloned. Only the members. On the other hand keeping the 2 classes as references works just fine when I switch back and forth (between proposalDetails and orderDetails)
Is there a reason that keeping reference is bad/incorrect practice?
Is there any danger that when I modify proposalDetails, orderDetails is modified too?
switchView(viewName) {
if (viewName === 'proposal') {
//this.orderBackup = JSON.parse(JSON.stringify(this.orderDetails));
//this.orderDetails = JSON.parse(JSON.stringify(this.proposalDetails));
//'Cloning' the member like this does not include all the class functions
//I changed it to keep just the reference
this.orderBackup = this.orderDetails;
this.orderDetails = this.proposalDetails;
$('#view_ordered').removeClass('active');
$('#view_proposal').addClass('active');
this.formDisabled = true;
return;
}
this.orderDetails = this.orderBackup;
}
What you're asking isn't specific to Aurelia at all, other than the fact Aurelia promotes the use of classes for your view-models. I have used the JSON trick you are using to do simple clones of classes, it gets the job done and to be honest isn't the worse thing you can do.
Worth pointing out that Lodash has some great utility functions for cloning objects both deep and shallow as well.
Related
at the moment I'm writing a small app and came to the point, where I thought it would be clever to clone an object, instead of using a reference.
The reason I'm doing this is, because I'm collecting objects in a list. Later I will only work with this list, because it's part of a model. The reference isn't something I need and I want to avoid having references to outside objects in the list, because I don't want someone to build a construct, where the model can be changed from an inconsiderate place in their code. (The integrity of the information in the model is very important.)
Additional I thought I will get a better performance out of it, when I don't use references.
So my overall question still is: When should I prefer a clone over an reference in javascript?
Thanks!
If stability is important, then clone it. If testing shows that this is a bottleneck, consider changing it to a reference. I'd be very surprised if it is a bottleneck though, unless you have a very complicated object which is passed back and forth very frequently (and if you're doing that it's probably an indication of a bad design).
Also remember that you can only do so much to save other developers from their own stupidity. If they really want to break your API, they could just replace your functions with their own by copying the source or modifying it at runtime. If you document that the object must not be changed, a good developer (yes, there are some) will follow that rule.
For what it's worth, I've used both approaches in my own projects. For small structs which don't get passed around much, I've made copies for stability, and for larger data (e.g. 3D vertex data which may be passed around every frame), I don't copy.
Why not just make the objects stored in the list immutable? Instead of storing simple JSON-like objects you would store closures.
Say you have an object with two properties A and B. It looks like that:
myObj = {
"A" : "someValue",
"B" : "someOtherValue"
}
But then, as you said, anyone could alter the state of this object by simply overriding it's properties A or B. Instead of passing such objects in a list to the client, you could pass read-only data created from your actual objects.
First define a function that takes an ordinary object and returns a set of accessors to it:
var readOnlyObj = function(builder) {
return {
getA : function() { return builder.A; },
getB : function() { return builder.B; }
}
}
Then instead of your object myObj give the user readOnlyObj(myObj) so that they can access the properties by methods getA and getB.
This way you avoid the costs of cloning and provide a clear set of valid actions that a user can perform on your objects.
I'm developing a javascript library, composed by a main object, that works as a static Class and contains various objects that do the same thing.
I am having trouble finding the best way to refer to the objects in the documentation, as i am using jGrouse and it refers to them as Classes, like:
public Class myLibrary
None of these objects and it's children will have any primitive type variables nor will have any factory pattern associated so, they are not to be reinstantiated.
I can't show you a live example, but i'll try to put here an analogous one:
var myLibrary = {};
myLibrary.methodOne = function(){ ... };
myLibrary.methodTwo = function(){ ... };
// this is a sub-library that will encapsulate methods for Array type operations
myLibrary.Array = {};
myLibrary.Array.forEach = function(array, function(item));
(...)
// this is a sub-library that will encapsulate methods for Event type operations
myLibrary.Events = {};
(...)
So, i don't think it's correct to refer to myLibrary, myLibrary.Array and myLibrary.Events as Classes, for the obvious reason that they are not meant to be instantiated.
I reject the idea to call them Static Classes as Javascript isn't design to work with static classes per se.
I think Object and Inner Object or Static Object may not be the way to go also.
I'm looking for the best way to identify them in my public documentation, as for not to confuse unexperienced programmers nor insult the more advanced developers.
Any help?
thanx
Your probably looking for the term "namespace".
You really shouldn't worry so much about the correct word. The are all far too vague and have completely separate meaning is several different meanings in JavaScript sub cultures.
The important thing to say in documentation is that "The Event has these methods".
I want to see the method signatures, I want to see a high level description of what they do and I want to see an example.
perf
Why do we build a prototype inheritance chain rather then using object composition. Looking up through the prototype for each step in the chain get's expensive.
Here is some dummy example code :
var lower = {
"foo": "bar"
};
var upper = {
"bar": "foo"
};
var chained = Object.create(lower, pd(upper));
var chainedPrototype = Object.create(chained);
var combinedPrototype = Object.create(pd.merge(lower, upper));
var o1 = Object.create(chainedPrototypes);
var o2 = Object.create(combinedPrototypes);
uses pd because property descriptors are verbose as hell.
o2.foo is faster then o1.foo since it only goes up two prototype chain rather then three.
Since travelling up the prototype chain is expensive why do we construct one instead of using object composition?
Another better example would be :
var Element = {
// Element methods
}
var Node = {
// Node methods
}
var setUpChain = Object.create(Element, pd(Node));
var chained = Object.create(setUpChain);
var combined = Object.create(pd.merge(Node, Element));
document.createChainedElement = function() {
return Object.create(chained);
}
document.createCombinedElement = function() {
return Object.create(combined);
}
I do not see any code merging prototype objects for efficiency. I see a lot of code building chained prototypes. Why is the latter more popular?
The only reason I can think of is using Object.isPrototypeOf to test for individual prototypes in your chain.
Apart from isPrototypeOf are there clear advantages to using inheritance over composition?
The main reason would have to be changes to the prototype object. A change to an ancestor object will be reflected across the entire chain. This could, conceivably, be a benefit. Though I can't immediately think of any real-world instances, I think embracing this dynamic nature could provide a dynamic that other (read: class-based) languages simply don't provide.
Objects further up the prototype chain could evolve as needed across the lifetime of an application, and those changes would be reflected across all descendant objects. This could be easily combined with JavaScript's functions as first-class objects to dynamically modify functionality as needed.
That said, if this functionality is not necessary, there is no reason to use the prototype chain over composition.
Well, consider what would happen if lower or upper changed. The combined prototype wouldn't reflect that change since you've created a new object by copying properties from them.
For many situations that would be fine, but it's sure not as dynamic as actually constructing proper prototype chains for your objects.
Here are some benefits I can think of in order of importance
Memory usage
By using the prototype, you create shared properties. Your approach copies all the values to each object.
Upfront cost of setting up objects
Thought you are saving a little bit of time later, you are incurring the cost of copying properties when you set up the object. It'd be nice for you to account for that in your performance tests. This is a benefit that may be outweighed if you read a lot more than you set up your objects.
instanceOf
Good code doesn't use instanceOf, but sometimes you can't make all your code perfect, so why break a language feature?
Dynamically changing the prototype
Most people will claim that they never need this (like me), but many of us have extended Array.prototype after instantiating some arrays (not that you should do it). With the copy properties approach you lose the reference to the original object.
Unashamed plug: http://js-bits.blogspot.com/2010/08/javascript-inheritance-done-right.html
Last Note If you this is actually a bottleneck in an app, I would not be reluctant to use it for the objects in question
Forgive my probably incorrect application of terminology in this question (btw, please correct me where wrong).
Let's say we have a custom object we want to define. Some of the methods on this object make sense to be 'instance' specific. And we also have some methods that are really independent of the instance, sort of like a public static method in a language like C# or Java.
What is the standard practice for creating these functional definitions? Currently, I am doing something like this:
var User = function(name){
this.Name = name;
User.instances.push(this);
};
User.instances = [];
User.doSomething = function(){
// do something interesting with the set of user instances
};
var me = new User('me');
var you = new User('you');
User.instances; // => [me, you]
Notice how the 'static' methods get defined in a completely different section from the prototype/instance methods. They just don't feel connected looking at the code. In my ideal world, I would be able to define everything together (perhaps inside the User = function(){}?), to keep the code a little cleaner and connected. I understand one of the powers of JS is you can do things separate and modify on the fly. Just curious what the standard practice is on something like this.
Sometimes I just nest the 'static' definitions in some brackets - even though the brackets are actually syntactically meaningless:
// Static definitions
{
User.instances = [];
User.doSomething = function(){
// do something interesting with the set of user instances
};
}
Is there a standard practice that I am unaware of?
Your approach is perfectly fine, although you can - if you really insist - try to do wacky tricks like assigning these static attributes inside a constructor conditionally based on whether they were already assigned.
IMHO this will not make it more readable but will have worse performing code due to the test (if you create lots of these User objects)
I'm new to object oriented programming and am slowly learning how to apply it to javascript. So please bear with me. :)
I have two basic objects:
"record" which contains methods for editing a single record from a recordset. (create, save, load, etc.)
"recordList" which contains methods for outputting a paginated list of record titles.
I would like for these objects to be able to work together. For example, if record.save() is called, recordList.refresh() is also called, so that the paginated list reflects the updated data.
To accomplish this, I have created a third object "control" which contains instances of both "record" and "recordList". I am using "control" in the following fashion:
control = {}
control.record = object.create("record");
control.recordList = object.create("recordList");
control.save = function() {
this.record.save();
this.recordList.refresh();
};
This works. But I am wondering, is it proper? (I want to be sure I am not violating any of the rules of OO design in doing this.) Is there a better way?
Thanks in advance for your help.
Speaking from an OOP perspective, I don't think a record would save itself. A record in a database is simply data, and the database itself is what does things with that data, whether it's saving or loading or etc. That being said I'd make record be simply an object that holds data and would create a recordset object for interacting with the data. Within that recordset object you could put your recordList and update it accordingly. Something like:
var recordset = function() {
var me = this;
var currentRecord = object.create("record");
var recordList = object.create("recordList");
me.save = function() {
//Insert record.save code here
recordList.refresh();
};
};
Something to note about that code. In that setup currentRecord and recordList can't be accessed from outside the function and therefore you have encapsulation, one of the hallmarks of OOP. This is because the recordset function is a closure that "closes over" all variables within, meaning that every function within has access to the variables within the scope of recordset.
You could let the outside world get access through get or set functions:
me.getRecordList = function() {
return recordList.getArray(); //Not generally a good idea to simply return your internal object
};
Your solution is fine. Two minor suggestions for improvement
Use a more specific name than control (even 'recordControl' is ok). You may end up with lots of controls for different feature sets.
Use an object literal to create the entire object. Keeps your code tidier and more readable (and saves a few bytes)
(apologies for lack of spacing - editor not doing what I want it to do!)
recordControl = {
record : object.create("record"),
recordList : object.create("recordList"),
save : function() {
this.record.save();
this.recordList.refresh();
}
}
If it's one thing I've learned over time, it is that following any paradigm to the letter will result in more frustration and difficulty than taking the concept as far as you can go and using common sense to dictate your deviations.
That said, your solution will work fine and it's normal to create a container class for multiple objects of varying types that are coupled. If you want a different way to handle it, check out Client Event Pooling. The only thing that I can say about what you've done is to be sure you're using object.create the way it was intended.
Using this method you can create an event, which when triggered will perform a series of other commands that are associated with your event. I have used this with great success in all sorts of applications, from the intended event hooking to simplifying inline javascript injections after a postback.
Good luck.
why don't you provide your recordList into record?
var record = object.create("record");
record.recordList = object.create('recordList');
record.save = function(){
/*
do something
*/
this.recordList.refresh();
}