Encapsulation of functions | Purpose in terms of OO - javascript

Encapsulation is the core tenent of OO programming.
However, if you make a function private and then you return it so that you can use it, does this to anything effectively.
I would think not, that b.c. if you return a function , you are not returning a copy of it...you are returning a reference. That is the core of the question. When you return a function is it a copy or is it a reference to the actual function.
Does the code below keep func1 private and safe as good practice OO programming would like.
Or does encapsulation / data hiding not really pertain to functions?
var A = (function(){
var func1 = function(param){
// do stuff
},
publik;
publik.retFunc(){
return func1;
}
return publik;
}())
A.retFunc()(arg1);

I'm really not sure where you're going with this...
But, to further the cause:
var Class = (function () {
var private_data = 1234,
private_method = function (x) { private_data += x; },
public_method = function (x) { private_method(x); },
other_method = function () { return private_data; },
public_interface = {
add : public_method,
toString : other_method
};
return public_interface;
}());
I have now programmed to an interface.
This particular interface would be .add and .toString.
The private values are safe from tampering, as they've been enclosed.
add has the ability to access private_method so long as add isn't modified.
See, if you try to do something like this, after the fact:
Class.add = function (x) { steal(private_data + x); };
It's not going to work.
The new function doesn't have a reference to the private data.
So while an external person or program might tamper with the public interface, the internal state is still fine.
Your program will likely still break if it's been tampered with, or other, less protected classes might get compromised, but this one will sit happily, and any internal calls it needs to make (like if it updated a screen, on a timer), will still happen perfectly.
The other point of encapsulation is to choose the interface that you want to present to people.
You could have 30 helper functions inside of a class, but you probably only want to give the external application access to a few of them.
And those public methods will have access to the private data/methods, and the ability to do whatever it is you want the clients to be able to do, and nothing more.
That's an Application Programming Interface.
If I wanted to have a BlogManager class, it might be huge.
Maybe I want it to be able to get stuff from the database, to sort, to set up templates, or to communicate with a view... I want it to be able to filter, I want it to do all kinds of stuff...
But I don't want the end-user to do all of that.
What I want the end user to do is .request(options); or .create(blog_post); or .update(blog_post); or .delete(blog_post);.
If I give the end-user those four methods then nobody can touch the dozens of other things going on inside of the BlogManager to make everything work as expected.
That's programming to an interface.
In the future, when I figure out a better way to filter my results, or when I change my database, or when I change the structure of the data-storage, it isn't going to matter what I do on the inside of my class, because the outside will still look and act the same.
If it has the same public methods, the same input-types, the same return-types... ...then you can do anything you want inside.
There aren't a lot of immediate cases for returning the actual constructor-function, instead of an instated object, though.
Much like there aren't a lot of cases for returning the function, instead of the function's return-value.
Aside from asynchronous programming.

Related

No ways to have class-based objects in javascript?

The javascript prototype-based object-oriented programming style is interesting, but there are a lot of situations where you need the ability to create objects from a class.
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
I've read a lot of tutorials and the book "Javascript : the good parts", but yet it seems to me that there is no way to define classes that respect 1) encapsulation and 2) efficient member methods declaration (I mean : member methods that are being defined once, and shared among every class instances).
To define private variables, closures are being used :
function ClassA()
{
var value = 1;
this.getValue = function()
{
return value;
}
}
The problem here is that every instance of "ClassA" will have its own copy of the member function "getValue", which is not efficient.
To define member functions efficiently, prototype is being used :
function ClassB()
{
this.value = 1;
}
ClassB.prototype.getValue = function()
{
return this.value;
}
The problem here is that the member variable "value" is public.
I don't think that this issue can be solved easily, since "private" variables need to be defined DURING object creation (so that the object can have access to its context of creation, without exposing thoses values) whereas prototype-based member functions definition has to be done AFTER object creation, so that prototype makes sense ("this.prototype" does not exists, I've checked).
Or am I missing something ?
EDIT :
First of all, thank you for your interesting answers.
I just wanted to add a little precision to my initial message :
What I really want to do is to have 1) private variables (encapsulation is good, because people only have access to what they need) and 2) efficient member methods declaration (avoid copies).
It seems that simple private variables declaration can really only be achieved via closure in javascript, that's essentially why I focused on the class based approach. If there is a way to achieve simple private variables declaration with a prototype based approach, that's okay for me, I'm not a fierce class-based approach proponnent.
After reading the answers, it seems like the simple solution is to forget about privates, and use a special coding conventions to detter other programmers from accessing "private" variables directly...
And I agree, my title / first sentence was misleading regarding the issue I wanted to discuss here.
Shh, come here! Wanna hear a secret?
Classical inheritance is a tested and tried approach.
It is useful to implement it in JavaScript often. Classes are a nice concept to have and having templates for modeling our world after objects is awesome.
Classical inheritance is just a pattern. It's perfectly OK to implement classical inheritance in JavaScript if it's the pattern you need for your use case.
Prototypical inheritance focuses on sharing functionality and that's awesome (dinasaur drumstick awesome), but in some cases you want to share a data-scheme and not functionality. That's a problem prototypical inheritance does not address at all.
So, you're telling me classes are not evil like everyone keeps telling me?
No, they are not. What the JS community frowns upon is not the concept of classes, it's limiting yourself to just classes for code reuse. Just like the language does not enforce strong or static typing, it doesn't enforce schemes on object structure.
In fact, behind the scene clever implementations of the language can turn your normal objects to something resembling classical inheritance classes.
So, how do classes work in JavaScript
Well, you really only need a constructor:
function getVehicle(engine){
return { engine : engine };
}
var v = getVehicle("V6");
v.engine;//v6
We now have a vehicle class. We didn't need to define a Vehicle class explicitly using a special keyword. Now, some people don't like to do things this way and are used to the more classical way. For this JS provides (silly imho) syntactic sugar by doing:
function Vehicle(engine){
this.engine = engine;
}
var v = new Vehicle("V6");
v.engine;//v6
That's the same thing as the example above for the most part.
So, what are we still missing?
Inheritance and private members.
What if I told you basic subtyping is very simple in JavaScript?
JavaScript's notion of typing is different than what we're used to in other languages. What does it mean to be a sub-type of some type in JS?
var a = {x:5};
var b = {x:3,y:3};
Is the type of b a sub type of the type of a? Let's say if it is according to (strong) behavioral subtyping (the LSP):
<<<< Begin technical part
Contravariance of method arguments in the subtype - Is fully preserved in this sort of inheritance.
Covariance of return types in the subtype - Is fully preserved in this sort of inheritance.
No new exceptions should be thrown by methods of the subtype, except where those exceptions are themselves subtypes of exceptions thrown by the methods of the supertype. - Is fully preserved in this sort of inheritance.
Also,
Preconditions cannot be strengthened in a subtype.
Postconditions cannot be weakened in a subtype.
Invariants of the supertype must be preserved in a subtype.
The history rule
All of these are again, are up to us to keep. We can keep them as tightly or loosly as we want, we don't have to, but we surely can.
So matter of fact, as long as we abide to these rules above when implementing our inheritance, we're fully implementing strong behavioral subtyping, which is a very powerful form of subtyping (see note*).
>>>>> End technical part
Trivially, one can also see that structural subtyping holds.
How would this apply to our Car example?
function getCar(typeOfCar){
var v = getVehicle("CarEngine");
v.typeOfCar = typeOfCar;
return v;
}
v = getCar("Honda");
v.typeOfCar;//Honda;
v.engine;//CarEngine
Not too hard, was it? What about private members?
function getVehicle(engine){
var secret = "Hello"
return {
engine : engine,
getSecret : function() {
return secret;
}
};
}
See, secret is a closure variable. It's perfectly "private", it works differently than privates in languages like Java, but it's impossible to access from the outside.
What about having privates in functions?
Ah! That's a great question.
If we want to use a private variable in a function we share on the prototype we need to firrst understand how JS closures and functions work.
In JavaScript functions are first class. This means you can pass functions around.
function getPerson(name){
var greeting = "Hello " + name;
return {
greet : function() {
return greeting;
}
};
}
var a = getPerson("thomasc");
a.greet(); //Hello thomasc
So far so good, but we can pass that function bounded to a around to other objects! This lets you do very loose decoupling which is awesome.
var b = a.greet;
b(); //Hello thomasc
Wait! How did b know the person's name is thomasc? That's just the magic of closures. Pretty awesome huh?
You might be worried about performance. Let me tell you how I learned to stop worrying and started to love the optimizing JIT.
In practice, having copies of functions like that is not a big issue. Functions in javascript are all about well, functionality! Closures are an awesome concept, once you grasp and master them you see it's well worth it, and the performance hit really isn't that meaningful. JS is getting faster every day, don't worry about these sort of performance issues.
If you think it's complicated, the following is also very legitimate. A common contract with other developers simply says "If my variable starts with _ don't touch it, we are both consenting adults". This would look something like:
function getPerson(name){
var greeter = {
greet : function() {
return "Hello" +greeter._name;
}
};
greeter._name = name;
return greeter;
}
Or in classical style
function Person(name){
this._name = name;
this.greet = function(){
return "Hello "+this._name;
}
}
Or if you'd like to cache the function on the prototype instead of instantiate copies:
function Person(name){
this._name = name;
}
Person.prototype.greet = function(){
return "Hello "+this._name;
}
So, to sum it up:
You can use classical inheritance patterns, they are useful for sharing types of data
You should also use prototypical inheritance, it is just as potent, and much more in cases you want to share functionality.
TheifMaster pretty much nailed it. Having privates private is really not a big deal as one might think in JavaScript, as long as your code defines a clear interface this should not be problematic at all. We're all concenting adults here :)
*The clever reader might think: Huh? Weren't you tricking me there with the history rule? I mean, property access isn't encapsulated.
I say no, I was not. Even if you don't explicitly encapsulate the fields as private, you can simply define your contract in a way that does not access them. Often like TheifMaster suggested with _. Also, I think the history rule is not that big of a deal in a lot of such scenarios as long as we're not changing the way property access treats properties of the parent object. Again, it's up to us.
I don't want to be discouraging since you seem to be a fairly new member of StackOverflow, however I'm going to have to be a little in your face and say that it's a really bad idea to try to implement classical inheritance in JavaScript.
Note: When I say that it's a bad idea to implement classical inheritance in JavaScript I mean that trying to simulate actual classes, interfaces, access modifiers, etc. in JavaScript is a bad idea. Nevertheless, classical inheritance as a design pattern in JavaScript is useful as it's just syntactic sugar for prototypal inheritance (e.g. maximally minimal classes). I use this design pattern in my code all the time (a la augment).
JavaScript is a prototypal object-oriented programming language. Not a classical object-oriented programming language. Sure, you can implement classical inheritance on top of JavaScript but before you do keep the following things in mind:
You're going against the spirit of the language, which means that you'll be faced with problems. Lots of problems - performance, readability, maintainability, etc.
You don't need classes. Thomas, I know that you truly believe that you need classes but trust me on this. You don't.
For your sake I'll provide two answers to this question. The first one will show you how to do classical inheritance in JavaScript. The second one (which I recommend) will teach you to embrace prototypal inheritance.
Classical Inheritance in JavaScript
Most programmers start with trying to implement classical inheritance in JavaScript. Even JavaScript Gurus like Douglas Crockford tried to implement classical inheritance in JavaScript. I too tried to implement classical inheritance in JavaScript.
First I created a library called Clockwork and then augment. However I wouldn't recommend you to use either of these libraries because they go against the spirit of JavaScript. The truth is that I was still an amateur JavaScript programmer when I wrote these classical inheritance libraries.
The only reason I mention this is because everyone is an amateur at some point of time, and although I would prefer that you didn't use classical inheritance patterns in JavaScript, I can't expect you to understand why prototypal inheritance matters just yet.
You can't learn how to cycle without falling down a few times. I believe you're still in the learning phase with respect to prototypal inheritance. Your need for classical inheritance is like the training wheels on cycles.
Nevertheless, training wheels are important. If you want there are some classical inheritance libraries out there which should make you more comfortable writing code in JavaScript. One such library is jTypes. Just remember to take off the training wheels when you are confident of your skills as a JavaScript programmer.
Note: Personally I don't like jTypes one bit.
Prototypal Inheritance in JavaScript
I'm writing this section as a milestone for you so that you can come back later and know what to do next when you are ready to learn about true prototypal inheritance.
First of all the following line is wrong:
The javascript prototype-based object-oriented programming style is interesting, but there are a lot of situations where you need the ability to create objects from a class.
This is wrong because:
You will never need to create objects from a class in JavaScript.
There is no way to create a class in JavaScript.
Yes it's possible to simulate classical inheritance in JavaScript. However you're still inheriting properties from objects and not classes. For example, ECMAScript Harmony classes are just syntactic sugar for the classical pattern of prototypal inheritance.
In the same context the example you gave is also wrong:
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
Yes you can create a new line from an existing one even though the workspace is empty in the beginning. What you need to understand is that the line is not actually drawn though.
var line = {
x1: 0,
y1: 0,
x2: 0,
y2: 0,
draw: function () {
// drawing logic
},
create: function (x1, y1, x2, y2) {
var line = Object.create(this);
line.x1 = x1;
line.y1 = y1;
line.x2 = x2;
line.y2 = y2;
return line;
}
};
Now you can draw your the above line by simply calling line.draw or else you could create a new line from it:
var line2 = line.create(0, 0, 0, 100);
var line3 = line.create(0, 100, 100, 100);
var line4 = line.create(100, 100, 100, 0);
var line5 = line.create(100, 0, 0, 0);
line2.draw();
line3.draw();
line4.draw();
line5.draw();
The lines line2, line3, line4 and line5 form a 100x100 square when drawn.
Conclusion
So you see you really don't need classes in JavaScript. Objects are enough. Encapsulation can be easily achieved using functions.
That being said you can't have public functions of each instance access the private state of the object without each instance having its own set of public functions.
This is not a problem however because:
You don't really need private state. You may think that you do, but you really don't.
If you really want to make a variable private then as ThiefMaster mentioned just prefix the variable name with an underscore and tell your users not to mess with it.
Aight, here's my attempt at solving this particular issue, although I think following conventions it's a better approach, ie. prefix your variables with _. Here I just keep track of the instances in an array, they can then be removed with a _destroy method. I'm sure this can be improved but hopefully it will give you some ideas:
var Class = (function ClassModule() {
var private = []; // array of objects of private variables
function Class(value) {
this._init();
this._set('value', value);
}
Class.prototype = {
// create new instance
_init: function() {
this.instance = private.length;
private.push({ instance: this.instance });
},
// get private variable
_get: function(prop) {
return private[this.instance][prop];
},
// set private variable
_set: function(prop, value) {
return private[this.instance][prop] = value;
},
// remove private variables
_destroy: function() {
delete private[this.instance];
},
getValue: function() {
return this._get('value');
}
};
return Class;
}());
var a = new Class('foo');
var b = new Class('baz');
console.log(a.getValue()); //=> foo
console.log(b.getValue()); //=> baz
a._destroy();
console.log(b.getValue()); //=> baz
You don't need private/public at runtime. These are enforceable statically. Any project complex enough to enforce private properties are not used outside will have a build/pre-process step, which you can use
to verify the fact. Even languages with syntax for private/public have a way to access private at runtime.
As for defining class-based objects, the constructor+prototype you are using is the simplest and most efficient way. Any kind of additional wizardry will
be more complex and less performant.
Although you can cache prototype so you don't have to repeat ClassB.prototype. all the time:
//in node.js you can leave the wrapper function out
var ClassB = (function() {
var method = ClassB.prototype;
function ClassB( value ) {
this._value = value;
}
method.getValue = function() {
return this._value;
};
method.setValue = function( value ) {
this._value = value;
};
return ClassB;
})();
The above does not require any library and you can easily create a macro for it.
Also, in this case even a regex is enough to verify
that "private" properties are used correctly. Run /([a-zA-Z$_-][a-zA-Z0-9$_-]*)\._.+/g through the file and see that the first match
is always this. http://jsfiddle.net/7gumy/
It's impossible as far as I know without other instances influencing the value, so if it's a constant you're still good by wrapping it in a function like this:
(function( context ) {
'use strict';
var SOME_CONSTANT = 'Hello World';
var SomeObject = function() {};
SomeObject.prototype.sayHello = function() {
console.log(SOME_CONSTANT);
};
context.SomeObject = SomeObject;
})( this );
var someInstance = new SomeObject();
someInstance.sayHello();
The best you could do is annotate that a property shouldn't be touched by using an underscore like this._value instead of this.value.
Note that private functions are possible by hiding them in a function:
(function( context ) {
'use strict';
var SomeObject = function() {};
var getMessage = function() {
return 'Hello World';
};
SomeObject.prototype.sayHello = function() {
console.log(getMessage());
};
context.SomeObject = SomeObject;
})( this );
var someInstance = new SomeObject();
someInstance.sayHello();
Here is an example of 2 'Classes' extending and interacting with each other: http://jsfiddle.net/TV3H3/
If you really want private entities on a per instance basis, but still want to inherit your methods, you could use the following set-up:
var Bundle = (function(){
var local = {}, constructor = function(){
if ( this instanceof constructor ) {
local[(this.id = constructor.id++)] = {
data: 123
};
}
};
constructor.id = 0;
constructor.prototype.exampleMethod = function(){
return local[this.id].data;
}
return constructor;
})();
Now if you create a new Bundle, the data value is locked away inside:
var a = new Bundle(); console.log( a.exampleMethod() ); /// 123
However you now get into the debate as to whether you should truly have private values in JavaScript. As far as I've found it's always better for those that may need to extend your code—even yourself—to have open access to everything.
There are also hidden downsides to the above pattern, besides not being so readable, or being clunky to access "private" values. One fact is that every single instance of Bundle will retain a reference to the local object. This could mean—for example—if you created thousands of Bundles, and deleted all but one of them, the data held in local would not be garbage collected for all Bundles ever created. You'd have to include some deconstruction code to fix that... basically making things more complicated.
So I'd recommend dropping the idea of private entities / properties, whichever pattern you decide to go for... object-based or constructor. The benefit of JavaScript is that all these different approaches are possible—it's no-where-near as clear cut as class-based languages—which some could argue makes things confusing, but I like the freedom JavaScript lends towards being quick and expressive.
with regards this statement in your question:
For instance in a vector drawing application, the workspace will usually be empty at the beginning of the drawing : I cannot create a new "line" from an existing one. More generally, every situation where objects are being dynamically created require the use of classes.
You seem to be under the misunderstanding that objects in Javascript can only be made by cloning existing objects, which would backtrack to the problem of "okay but what about the very first object? that can't be made by cloning an existing object because there aren't any existing objects."
However you can make objects from scratch, and the syntax for that is as simple as var object = {}
I mean, that's the simplest possible object, an empty object. More useful of course would be an object with stuff in it:
var object = {
name: "Thing",
value: 0,
method: function() {
return true;
}
}
and so on, and now you're off to the races!
There are cleverer people than I answering this question, but I wanted to note one part in particular that you just edited in - the private variable part.
You can simulate this using closures; an awesome construct which allows a function to have it's own environment. You could do this:
var line = (function() {
var length = 0;
return {
setLen : function (newLen) {
length = newLen;
},
getLen : function () {
return length;
}
};
}());
This will set line to be an object with the setLen and getLen methods, but you'll have no way of manually accessing length without using those methods.

JavaScript style and standard practice - "static" method definition of custom user function/object

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)

Javascript: should I be hiding my implementations?

As a C# programmer, I have a bit of a habit of making things private that can and should be private, and I always get a weird feeling when a JS type exposes all its private parts to me (and that feeling is not 'aroused'). Say I have a type that has a draw method, which internally calls drawBackground and drawForeground, which make no sense to be called on their own. How should I implement this?
Option 1
Foo = function(){
this.draw();
};
Foo.prototype.draw = function(){
this.drawBackground();
this.drawForeground();
};
Foo.prototype.drawBackground = function(){};
Foo.prototype.drawForeground = function(){};
Option 2
Foo = (function(){
var constructor = function(){
this.draw();
};
var drawBackground = function(){};
var drawForeground = function(){};
constructor.prototype.draw = function(){
drawBackground.call(this);
drawForeground.call(this);
};
return constructor;
})();
The difference, of course, being that in the first example, the drawBackground and drawForeground methods are part of the public API, while they are hidden to the outside in the second one. Is that desirable? Which one should I prefer? Am I wrong to apply my C# habits to Javascript and should I make everything extensible and override-able in Javascript? And what are the performance implications of the .call(this)?
There's a well known quote amongst Perl developers that comes from the (in)famous Camel book: "A Perl module would prefer that you stay out of its living room because you weren't invited, not because it has a shotgun.". The philosophy being, if you as the developer of a library want to distinguish between your public and private API, that's great. Do that and document it. The caller of your code should know which is which, but also be free to act like an idiot if they decide to and call things you don't think they should call. From an OO background, that's heretical, but with scripting languages, that's how they roll.
The answer to this is a bit subjective, but I'll tell you that when I'm writing JavaScript and have methods or variables that would be private if I were coding in .NET, I just prefix them with something like "prv_" or "p_" or just "_"... whatever floats your boat. That way, you've told your users that this stuff is meant to be private and could change out from under them. And that way, if they choose to call your private methods anyway, that iffy code will stick out like a sore thumb.

What is the proper way to control related objects in javascript?

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();
}

Testing JavaScript functions inside anonymous functions

Is it possible to test myInnerFunction below?
var val = function() {
var myInnerfunction = function(input) {
return input + ' I ADDED THIS';
};
return myInnerfunction('test value');
}();
Because myInnerFunction is essentially a private member of the anonymously executed outer function, it doesn't seem like it is testable from the outside.
You could intentionally expose a testing hook to the outside world, like possibly this:
var val = function() {
var myInnerfunction = function(input) {
return input + ' I ADDED THIS';
};
/* START test hook */
arguments.callee.__test_inner = myInnerFunction;
/* END test hook */
return myInnerfunction('test value');
}();
now, once val has been run at least once, you can reference val.__test_inner and call it with testable inputs.
The benefits to this approach:
1. you choose what is exposed and not (also a negative 'cause you have to REMEMBER to do so)
2. all you get is a copy-reference to the private method, so you can't accidentally change it, only use it and see what it produces
The drawbacks:
1. if the private member changes (or relies on) state of its host/parent function, it's harder for you to unit test around that, since you have to recreate or artificially control the host/parent state at the same time
2. As mentioned, these hooks have to be manually added
If you got really clever, you could have your build process look for blocks of comments like the above and remove the test hooks when creating your production build.
afaik unit testing does not concern about internal workings of things you test. The point is that you test the functionality ie: it does what it's supposed to do, not how it does it.
So if it uses an internal private member, it should not be testable...
You can test the external behavior that is observable. In this simple case you returned just the value of the inner function, but in a real world example you might combine the result of that inner function with something else. That combination is what you would test, not the direct outputs of the private method.
Trying to test the private method will make your code difficult to change and refactor, even when the external behavior is preserved. That said, I like to view unit tests not as extensive tests of your code, but simply providing an example of the API and how it behaves to different conditions. ;)
I think my answer for this is (like so many things) that I'm doing it wrong. What I've defined as a 'private' function is really something that needs to be tested. It was only private because I didn't want to expose it within a utilities api or something like that. But it could still be exposed through my application namespace.
So within the anonymous function that is executed on-dom-ready, I just attach my pre-defined functions as event handlers to the proper DOM hooks. The functions themselves, while not stored with my more open utilities functions, are still stored publicly within a package in my namespace associated with the DOM structure they are dealing with. This way I can get at them and test them appropriately.

Categories