jQuery and object-oriented JavaScript - howto? - javascript

I've read this and this (thanks google)
But it doesn't help enough. I'd like to know, if, straight out of the box, without any plugin addons, it's possible to do something like it's possible with prototype, for example:
MyClass = Class.create(Table,
{
cookieName: 'w_myclass',
prefix: 'myclass',
...blabla...
// function
initStr: function()
{
...blabla...
},
// another function
getIndice: function(param)
{
...blabla...
return 0;
}
});
Any idea/suggestions are welcome.

JQuery never had the purpose of being a class framework. It's about page manipulation and tools (like AJAX). You can pound a nail with a fork, but why not use a hammer?
Using native JavaScript to create a class-based inheritance system is asking for trouble unless you're a highly skilled JavaScript programmer. Douglas Crockford will tell you it's possible, but he has a deep understanding if the intricacies of closure etc etc. Also, using native inheritance features becomes unsustainable very quickly if your system grows large.
I highly recommend James Coglan's JS.Class framework. The class definitions will look almost identical to your example. It's not native JS but it works fine with JQuery.

If you want a near object oriented solution using javascript with jquery you can define an object in javascript that will set up your event controllers.
The second half of this post http://www.codescream.com/?p=18 covers that. but i'll write here a resume on how to make an object in javascript that you can use in a near object oriented structure.
It would look something like this:
function myObject(constructorParam1, constructorParam2, anotherOne, blabla){
var text = "";
// this event will be set everyTime you run myObject
$(".foo").click(function(){
text = $(this).text(); // copies the text inside the elements ".foo" to a local variable
doSomething();
});
function aPrivateFunction1(){
}
function aPrivateFunction2(){
}
function internalAdd(a,b){
return a+b;
}
var size = 1; // privateVaribale
var name = blabla;
if(name===undefined){
name="No name";
}
aPrivateFunction1(); // run "aPrivateFunction1()
// you can consider all code above as being part of the constructor.
// The variables declared above are private, and the functions are private as well
// bellow are public functions that you can access in an OOP manner
return {
getSize: function(){
return size;
},
setSize: function(newSize){
size = newSize;
},
getName: function(){
return name;
},
setName: function(newName){
name = newname;
},
addAndTurnPositive: function(n1,n2){
var val = internalAdd(n1,n2);
if(val<0){
return val*-1;
}
return val;
}
}
}
// then you can run it like
var anInstance = myObject("aaa",1234,"asdak",123);
anInstance.setSize(1234);
var t = anInstance.addAndTurnPositive(-5,2);

In a word, no. jQuery doesn't offer any class and inheritance functionality. You'd need to include another library, such as klass (although there is a jQuery plugin which ties it in more closely with jQuery)

Related

Is there a pattern in JavaScript for loosely coupled objects.

I'm relatively new to JavaScript so apologies if this type of question is an obvious one.
We have an app which uses etcd as its way to store data. What I'm trying to do is implement a way of swapping or alternating between different backend data stores (I'm wanting to use dynamodb).
I come from a C# background so if I was to implement this behaviour in an asp.net app I would use interfaces and dependancy injection.
The best solution I can think of is to have a factory which returns a data store object based upon some configuration setting. I know that TypeScript has interfaces but would prefer to stick to vanilla js if possible.
Any help would be appreciated. Thanks.
Interfaces are "merely" a static typing measure to implement polymorphism. Since Javascript doesn't have any static type system, it also doesn't have interfaces. But, it's a highly polymorphic language in itself. So what you want to do is trivial; simply don't write any interfaces as part of the process:
function StorageBackend1() { }
StorageBackend1.prototype.store = function (data) {
// here be dragons
};
function StorageBackend2() { }
StorageBackend2.prototype.store = function (data) {
// here be other dragons
};
function SomeModel(storage) {
this.storage = storage;
this.data = {};
}
SomeModel.prototype.saveData = function () {
this.storage.store(this.data);
};
var m1 = new SomeModel(new StorageBackend1),
m2 = new SomeModel(new StorageBackend2);
m1.saveData();
m2.saveData();
Using TypeScript and actual interfaces gives you the sanity of a statically type checked language with fewer possible surprises at runtime, but you don't need it for polymorphism.
I come from Delphi / C# etc. And interface are just a pain in the but.
Javascript is so much nicer..
With javascript interfaces are not needed, just add the method.
eg.
function MyBackend1() {
this.ver = 'myBackEnd1';
}
function MyBackend2() {
this.ver = 'myBackEnd2';
this.somefunc = function () { console.log('something'); }
}
function run(backend) {
console.log(backend.ver);
//below is like an interface supports
if (backend.somefunc) backend.somefunc();
}
run(new MyBackend2());
//lets now use backend1
run(new MyBackend1());

Javascript Module pattern - how to reveal all methods?

I have module pattern done like this:
var A = (function(x) {
var methodA = function() { ... }
var methodB = function() { ... }
var methodC = function() { ... }
...
...
return {
methA: methodA,
methB: methodB
}
})(window)
This code let's me call only methA and methB() on A which is what I want and what I like. Now the problem I have - I want to unit test it with no pain ot at least with minimal efforts.
First I though I can simply return this but I was wrong. It returns window object.(can someone explain why?).
Second - I found solution somewhere online - to include this method inside my return block:
__exec: function() {
var re = /(\(\))$/,
args = [].slice.call(arguments),
name = args.shift(),
is_method = re.test(name),
name = name.replace(re, ''),
target = eval(name);
return is_method ? target.apply(this, args) : target;
}
This method let's me call the methods like this: A.__exec('methA', arguments);
It is almost what I want, but quite ugly. I would prefer A.test.methA() where test would never be used in production code - just for revealing private methods.
EDIT
I see people telling me to test the big thing instead of the small parts. Let me explain. In my opinion API should reveal only the needed methods not a bunch of internal functions. The internals because of their small size and limited functionality are much easier to test then test the whole thing and guess which part gone wrong.
While I may be wrong, I would still like to see how I could return references to all the methods from the object itself :).
Answer to your first question(you return this, but it returns window, not the object you wanted): in javascript this inside the function returns global object unless this function is a method of the object.
Consider next examples:
1) this points to the global object ():
function(){
return this;
}
2) this points to the object:
var obj = {
value: "foo",
getThisObject: function(){
return this;
}
}
Your case is example #1, because you have a function, that returns an object. This function is not a method of any object.
The best answer to your second question is to test only public methods, but if
that is so important for you, I can propose next:
create your modules dynamically on server side.
How it works:
create separate scripts for functionality you want;
create tests for these separate scripts;
create method that will combine scripts into one however you want;
to load script, reference to the combining scripts method.
Hopefully, it can solve your problem. Good luck!
Why not use namespaces to add your modules and public methods to js engine. Like this:
window['MyApp']['MODULE1'] = { "METHOD1" : {}, "METHOD2" : {}};
I write modules like this Sample module in JavaScript.
And test it like this: Simple unit testing in JavaScript
The use of eval() is generally not good idea.

(Seemingly) redundant naming of functions in classes

I've seen various patterns in object creation, but upon diving into some Firefox framework Javascript, I'd noticed that they're using a convention that I haven't seen before and I'm hoping that someone here can either confirm my assumption or correct me:
When building a class, I've done this (and variations of) in the past:
function MyClass() {
this.myPublicFunction = function() {
};
var myPrivateFunction = function() {
};
}
Bound anonymous functions. Cool. This is what I've seen throughout most frameworks and such.
However, it seem that Mozilla does this:
function MyClass() {
this.myPublicFunction = function MYCLASS_myPublicFunction() {
};
var myPrivateFunction = function MYCLASS_myPrivateFunction() {
};
}
My assumption is that in using the latter convention, JS JIT compiles the functions, but wouldn't pick up the first two as they'd be defined at run-time rather than parse time.
Is this assumption correct and if so, does this also apply to other JS engines or just Spidermonkey?
Reasons to use NFE:
a function with a name gives more debugging information in your stack trace
NFE are self documenting. (if you put useful information in the name).
Note that function declarations are better then NFE. (From a personal style choice)
function MyClass() {
this.myPublicFunction = myPublicFunction;
function myPrivateFunction() {
}
function myPublicFunction() {
}
}
Also note that the word "private" is misleading, but that's a tangent.

Howto move from object based language to server side Node.js Javascript for big projects?

I've decided to get used to using Javascript as my server sided (I'm using Node.js) language to setup a webserver, create server deamons and a lot more. This is a rather big project, which means that I have to get used to the language and get myself an optimal setup before actually starting to avoid overhead and unneeded hassle.
I have been looking for sources that'd explain the basics of functional programming in big projects. Unfortunately, most sources talk only about basic Javascript meant for simple tricks in a browser.
Two helpful links that explained how object creation works in Javascript were http://howtonode.org/object-graphs and http://howtonode.org/object-graphs-2.
In the end, it seems most wise to create an object like:
function MyObject(constructorMemberOne, constructorMemberTwo) {
this.constructorMemberOne = constructorMemberOne;
this.constructorMemberTwo = constructorMembertwo;
this.doSomething = function doSomething() {
//
}
}
Now, I'm looking for a complete Javascript language reference. So far, https://developer.mozilla.org/en/JavaScript/Reference seems to be most complete.
Q1: is this the recommended ECMAScript language reference? I'm asking mostly because it's sourced by a company that's mostly working in the browser industry, yet Javascript is not just there for browsers -- maybe there are sources that I'm unaware of.
Secondly, I'm used to creating a new file for every class I create where the file name represents the name of the class. Q2: Is this recommended practice in Javascript (V8, Node.js) too? How would one "import" this class?
This "importing" leads me to my confusingness about Node.js's "require". I know it's not the same. Require basically loads another file which then has it's own namespace, meaning that it's variables are out of the scope of the file that's requireing this file. For my classes however, I want to have methods that are available to the class that is "importing" (quotes as I am not sure whether this is even possible) this class. Eg.:
var utils = require("utils/MainUtils.js");
utils.doSomething();
As far as I know, this doSomething() method is only available if it was set like:
function MainUtils() {
exports.doSomething = function doSomething() {
//
}
}
Q3: Is that correct? Doesn't that seem quite abnormal?
Q4: Are there any other blogs or resources that are helpful in getting my setup working, like howtonode.org?
Finally, Q5: have there been any efforts into making all this inheritance, object creation, project structure, namespacing etc. easier for big projects? Any libraries or something for this purpose?
Hopefully my questions are clear. Any help is appreciated. Thanks.
is this the recommended ECMAScript language reference?
Well the official ECMAScript language reference is the ECMA-262 itself. But unfortunately this is completely unreadable even by the standards of standards documents.
ECMA do not produce any materials aimed at end-programmers and there's no one tutorial considered “best”. The MDC link looks decent, at least. (Most JavaScript tutorials are absolutely horrible and full of errors. Which is partly JavaScript's fault for having so many... quirky... features, but still.)
In the end, it seems most wise to create an object like:
There is unfortunately no widely-accepted-‘best’ way to implement a class/instance system in JavaScript. A lot of frameworks have their own systems, or you can brew your own. Your example code creates a new instance of each method for each object instance, which you might consider suboptimal compared to JS's native prototyping. (Normally this approach is used with a var that= this in the closure to avoid this-binding problems in callback code.) You would also need to exercise care in how you create subclasses and initialise them in the constructors.
See this question for a discussion on approaches to class/instance in JS.
I'm used to creating a new file for every class I create
Yeah, that's a Java wart you shouldn't bring to JS.
Keep your source files in manageable chunks of related classes and functions. Sometimes that will be one public class per file, more often it won't be.
How would one "import" this class?
JS itself has no native import functionality. In browsers you do it by inserting <script> tags or eval​ing code fetched by XMLHttpRequest, and have to take care of keeping variables in separate namespaces manually. In Node.js and other places where you're working with CommonJS, you use modules and require().
Is that correct?
Yes.
Doesn't that seem quite abnormal?
I don't think so. It's similar to other scripting languages, where it proves very useful. It's only really Java that forces you to wrap up a compilation unit into a single class.
I came up with the following after reading a book called Pro Javascript Design Patterns. However, I've been told that it's not good to think like this (private, public, static, etc.) in Javascript:
var SomeClass = (function() {
this.prototype.publicStaticMember = "this is a public static variable",
this.prototype.publicStaticMethod = function() {
return "this is a public method: cannot access private members/methods, but can access privileged and public members/methods";
}
var privateStaticMember = "this is a private static variable";
function privateStaticMethod() {
return "this is a private static method: can only access private members/methods";
}
//instance part
return function() {
this.publicInstanceMember = "this is a public instance variable";
var privateInstanceMember = "this is a private instance variable";
this.publicInstanceMethod = function() {
return "this is a privileged method: can access both public and private members/methods";
}
var privateInstanceMethod = function() {
return "this is a private method: can access both public and private members/methods but is private";
}
}
})();
It'd be instantiated like this:
var someInstance = new SomeClass().("param1", "param2");
Any comments? Should I read an other book?
If you haven't already, checkout the videos by Douglas Crockford. He has a bunch of videos that talk about the prototypal aspects of JavaScript.
Google for 'Douglas Crockford Java Programming Language Video'. Here is a link to the first part in the series: http://video.yahoo.com/watch/111593/1710507
The defineClass npm package provides simple yet powerful OOP for JavaScript with support for traits (mixins) and nested classes. Here is an example of usage:
var defineClass = require("defineClass").defineClass;
var Person = defineClass({
cash: 0,
constructor: function (firstName, lastName) {
this.firstName = firstName;
this.lastName = lastName;
},
greet: function (name) {
console.log("Hello " + name + ". My name is " + this.firstName);
},
earn: function (amount) {
this.cash += amount;
}
});
var Developer = defineClass({
_super: Person,
// override a field default value
cash: 100,
// override the constructor
constructor: function (firstName, lastName, language) {
// you may have code before the base constructor call
// call the base constructor
this._super(firstName, lastName);
this.language = language;
}
// override a method
greet: function (name) {
console.log("Hey, " + name + ". I'm " + this.firstName)
},
// override a method and call its base method
earn: function (amount) {
return this._super(amount * 1.2);
}
});
Read more in the readme: https://github.com/nodirt/defineClass
Installation:
$ npm install defineClass

Object oriented javascript with prototypes vs closures

I'm curious what the difference is between the following OOP javascript techniques. They seem to end up doing the same thing but is one considered better than the other?
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
vs
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title;
};
return book;
}
var myBook = Book('War and Peace');
alert(myBook.getTitle())
The second one doesn't really create an instance, it simply returns an object. That means you can't take advantage of operators like instanceof. Eg. with the first case you can do if (myBook instanceof Book) to check if the variable is a type of Book, while with the second example this would fail.
If you want to specify your object methods in the constructor, this is the proper way to do it:
function Book(title) {
this.title = title;
this.getTitle = function () {
return this.title;
};
}
var myBook = new Book('War and Peace');
alert(myBook.getTitle())
While in this example the both behave the exact same way, there are differences. With closure-based implementation you can have private variables and methods (just don't expose them in the this object). So you can do something such as:
function Book(title) {
var title_;
this.getTitle = function() {
return title_;
};
this.setTitle = function(title) {
title_ = title;
};
// should use the setter in case it does something else than just assign
this.setTitle(title);
}
Code outside of the Book function can not access the member variable directly, they have to use the accessors.
Other big difference is performance; Prototype based classing is usually much faster, due to some overhead included in using closures. You can read about the performance differences in this article: http://blogs.msdn.com/b/kristoffer/archive/2007/02/13/javascript-prototype-versus-closure-execution-speed.aspx
Which is better can sometimes be defined by the context of their usage.
Three constraints of how I choose between Prototype and Closure methods of coding (I actively use both):
Performance/Resources
Compression requirements
Project Management
1. Performance/Resources
For a single instance of the object, either method is fine. Any speed advantages would most likely be negligible.
If I am instantiating 100,000 of these, like building a book library, then the Prototype Method would be preferred. All the .prototype. functions would only be created once, instead of these functions being created 100,000 times if using the Closure Method. Resources are not infinite.
2. Compression
Use the Closure Method if compression efficiency is important (ex: most browser libraries/modules). See below for explanation:
Compression - Prototype Method
function Book(title) {
this.title = title;
}
Book.prototype.getTitle = function () {
return this.title;
};
Is YUI compressed to
function Book(a){this.title=a}Book.prototype.getTitle=function(){return this.title};
A savings of about 18% (all spaces/tabs/returns). This method requires variables/functions to be exposed (this.variable=value) so every prototype function can access them. As such, these variables/functions can't be optimized in compression.
Compression - Closure Method
function Book(title) {
var title = title; // use var instead of this.title to make this a local variable
this.getTitle = function () {
return title;
};
}
Is YUI compressed to
function Book(a){var a=a;this.getTitle=function(){return a}};
A savings of about 33%. Local variables can be optimized. In a large module, with many support functions, this can have significant savings in compression.
3. Project Management
In a project with multiple developers, who could be working on the same module, I prefer the Prototype Method for that module, if not constrained by performance or compression.
For browser development, I can override the producton.prototype.aFunction from "production.js" in my own "test.js" (read in afterwords) for the purpose of testing or development, without having to modify the "production.js", which may be in active development by a different developer.
I'm not a big fan of complex GIT repository checkout/branch/merge/conflict flow. I prefer simple.
Also, the ability to redefine or "hijack" a module's function by a testbench can be beneficial, but too complicated to address here...
The former method is how JavaScript was intended to be used. The latter is the more modern technique, popularised in part by Douglas Crockford. This technique is much more flexible.
You could also do:
function Book(title) {
return {
getTitle: function () {
return title;
}
}
}
The returned object would just have an accessor called getTitle, which would return the argument, held in closure.
Crockford has a good page on Private Members in JavaScript - definitely worth a read to see the different options.
It's also a little bit about re-usability under the hood. In the first example with the Function.prototype property usage all the instances of the Book function-object will share the same copy of the getTitle method. While the second snippet will make the Book function execution create and keep in the heap 'bookshelf' different copies of the local closurable book object.
function Book(title) {
var book = {
title: title
};
book.getTitle = function () {
return this.title += '#';
};
return book;
}
var myBook = Book('War and Peace');
var myAnotherBook = Book('Anna Karenina');
alert(myBook.getTitle()); // War and Peace#
alert(myBook.getTitle()); // War and Peace##
alert(myAnotherBook.getTitle()); // Anna Karenina#
alert(myBook.getTitle());// War and Peace###
The prototype members exist in the only copy for all the new instances of the object on the other hand. So this is one more subtle difference between them that is not very obvious from the first sigh due to the closure trick.
here is an article about this
in general Book inharets from Book.prototype. In first example you add function to getTitle Book.prototype

Categories

Resources