Will there be a new way of managing javascript classes? - javascript

Does anyone know if structuring javascript will be changed? What I mean is to have a way to manage javascript classes into packages, like in Java. Is there already a way?

I guess you are familiar with the Java concept of naming packages after a domain you own, this way avoiding collision with the packages of other vendors. You can simulate Java packages (and avoid possible naemspace collisions) with:
if (typeof(org) == "undefined")
org = {};
if (typeof(org.mydomain) == "undefined")
org.mydomain = {};
if (typeof(org.mydomain.mypackage) == "undefined")
org.mydomain.mypackage = {};
org.mydomain.mypackage.MyClass = function (newA) {
// constructor
this.a = newA;
}
org.mydomain.mypackage.MyClass.staticMethod = function () {
// static method
return "static";
}
org.mydomain.mypackage.MyClass.prototype.method = function () {
// normal method
return a;
}
var o = new org.mydomain.mypackage.MyClass(13);
console.log(o.method());
console.log(org.mydomain.mypackage.MyClass.staticMethod());
You can even simulate Java's import if you are working in a limited scope. (Doing this in the global scope would eliminate the whole point of packaging):
function afunc() {
var MyClass = org.mydomain.mypackage.MyClass;
var o = new MyClass(33);
console.log(o.method());
console.log(MyClass.staticMethod());
}
The weakest link here is the root of our namespace, org (or com or any top level domain). An other class may use it for some other reasons. Using org_mydomain as the root instead of org.mydomain may give some safety.
Edit:
You have other possibilities for the root name too if you want to avoid using TLD as the root. If your domain name is unique enough (for example a hip misspelled one like foogz.com) you can assume that there will be no other company writing reusable JavaScript classes who will go for foogz.org or foogz.biz, so probably you will be the only foogz out there. :)
An other possibility is to append your TLD to the domain name and use that for the first tag for example: mydomainorg.packagename.ClassName.

There are no JavaScript classes. There are only Objects. You can pack a bunch of objects into a different object, and treat it like a module/namespace if you wish. (example at the end.)
Because of that, there can't be any "improvements" in the field of JavaScript classes because there aren't any, and I hope there won't ever be either. And frankly, that's for the best. Would you rather deal with insane getters/setters, static members, protected, type coercion and so on etc? Prototypal inheritance beats "Classical inheritance" by miles. It's just that JavaScript didn't have too much time to get it just right.
For amazing explanations on how JavaScript objects work, I recommend Douglas Crockfords' "On JavaScript", or some answers from our very own members.
An example of "namespacing":
var obj = {
classRoom : {...},
objectify : function() {...},
capacity : 5
};
var myClass = obj.classRoom; //access it like you access a module
var capacity = 7; //this is a global variable named capacity, so it won't tamper with obj.capacity

Check out http://joose.it, it has a great module system (library, not language extension). The 4th edition of the ECMA-262 spec has packages, and it's implemented in actionscript.

There is some speculation (e.g. by John Resig) about new features like object freezing and packages that might be added to ECMAScript Harmony (a.k.a 6th Edition).
However, I personally doubt that the language committee would consider such a drastic change to the way the language handles some of its core OO principles.

JavaScript is dynamic code in a file. All you do is load some source code and run it dynamically.
Every structuring and managing system is dynamically written and done at runtime. There are lots of ways you can manage and structure javascript code.
requirejs check define
yui check YUI.add
dojo check dojo.provide
and more
Personally I recommend requireJS as it's not tied into any framework / other libraries.

Related

Correct use of the JavaScript interface keyword

First of all, no, I'm not trying to create any sort of Java-like interface for my JavaScript code. I've seen those questions all over, and while I'm still a relative novice to JavaScript, I know those aren't part of the language.
However, I'm curious what the actual intended use of the interface keyword is. For example, Math is an interface, containing definitions (but not implementations). I believe (and may be totally wrong) that these are there to provide a means for the definers of the language to enforce a set of behaviors to be implemented in various JavaScript engines. Is that correct?
Furthermore, I have a desire to have a "static class" that contains a bunch of utility methods. I like that Math.sqrt(3) has an outer namespace ('Math') which is capitalized, and a number of logically similar methods and values in it. Maybe it's just my Java/Ruby background that makes me want a capital on the grouping objects. Is that bad form?
var ShapeInspections = {
isSymmetrical: function (s) {
// determine if shape is symmetrical
},
numAngles: function (s) {
// return the number of angles
}
}
A purely contrived example, but is it anti-idiomatic to name the "module" this way?
Okay, so as with other answers, you know that the keyword interface has no real use case in Javascript world, yet.
Your Math example made me suspicous that you are talking about a design pattern, called Module Pattern, widely used for scoping Javascript code. There are many ways of making your code modular. For example just like OddDev answered you , the famous Prototype Pattern can embed your code in a modular fashion (just like your Math example). Here is the Revealing Prototype Pattern example with also private variables and functions for additional flexibility:
/* Example from:
http://www.innoarchitech.com/scalable-maintainable-javascript-modules */
var myPrototypeModule = (function (){
var privateVar = "Alex Castrounis",
count = 0;
function PrototypeModule(name){
this.name = name;
}
function privateFunction() {
console.log( "Name:" + privateVar );
count++;
}
PrototypeModule.prototype.setName = function(strName){
this.name = strName;
};
PrototypeModule.prototype.getName = function(){
privateFunction();
};
return PrototypeModule;
})();
but that is not all. Other options include Scoped module pattern, POJO module pattern and many more. Have a look at How to Write Highly Scalable and Maintainable JavaScript: Modules, it has a very simple and yet thorough set of examples.
So far, we talked about plain Javascript. If you have the ability to use libraries in your code, then amazing set of libraries such as Requirejs, CommonsJS are there to help you on this with out-of-the-box functionalities. Have a look at Addy Osmani's post about Writing Modular JavaScript With AMD, CommonJS & ES Harmony.
The interface keyword in javascript is a FutureReservedWord, so it does absolutely nothing right now, though that may change in the future specifications. (See ECMAScript 5.1, section 7.6.1.2). In the ES6 draft, this is also the same.
As for you module, this is a perfectly idiomatic solution. It is always a good idea to "namespace" your functions, as it keeps the global scope as clean as possible.
I believe (and may be totally wrong) that these are there to provide a means for the definers of the language to enforce a set of behaviors to be implemented in various JS engines. Is that correct?
No, this is not correct. Things like "Math" etc. are objects containing functions. If you use for eyample "Math.pow(...)" you just execute the function stored in the "Math" object. Check this example:
var Math = {};
Math.prototype.pow = function(){
alert("stuff");
}
var ShapeInspections = { isSymmetrical: function (s) {
// determine if shape is symmetrical }, numAngles: function (s) {
// return the number of angles } } A purely contrived example, but is it anti-idomatic to name the "module" this way?
It's okay to name your objects like this. As already discussed "Math" is also just an object and follows these naming conventions.
To make things clear for the interface keyword:
The following tokens are also considered to be FutureReservedWords
when they occur within strict mode code (see 10.1.1). The occurrence
of any of these tokens within strict mode code in any context where
the occurrence of a FutureReservedWord would produce an error must
also produce an equivalent error:
implements let private public yield
interface package protected static
It's just reserved cause it's "may" needed in the future. So don't worry too much about it :) http://www.ecma-international.org/ecma-262/5.1/#sec-7.6
Do not confuse the "interfaces" that are specified in IDL with the interface keyword.
The latter is reserved for potential future use, but is not yet actually used in ECMAScript (not even in ES6).

Generation of getters and setters in Javascript compatible with Closure Compiler

I'm writing a library that I hope to be compatible with Closure Compiler in Advanced mode. Most objects in the library maintain an internal object of attributes that are frequently part of the API, which leads to my source files being filled with lots and lots of functions like this.
/*
* Get name.
*/
Layer.prototype.getName = function() {
return this.attrs.name;
}
/*
* Set name.
*/
Layer.prototype.setName = function(name) {
this.attrs.name = name;
}
I can think of a billion ways to optimize this to declutter my code a bit. One example: KineticJS, as per this related question, does something a bit like this:
Global.addGettersSetters = function(obj, property) {
obj['get'+property] = function() { return this.attrs[property] }
obj['set'+property] = function(val) { this.attrs[property] = val }
}
// Later that day, in our original object, we have:
Global.addGettersSetters(Layer, 'name');
My understanding is that this is a no-no with Closure Compiler--the names won't be shortened and the functions won't be optimized because I'm specifying the properties of Layer as strings.
So, is there a way for me to fully and properly define the interface without cluttering up my code? Something in the Closure Library I've overlooked, perhaps?
An alternative solution: is there a way to do C#-style properties in modern JS? In a way Closure Compiler finds permissible? I have the luxury of targeting Webkit and only Webkit with this library, so stuff that's not yet fully implemented is fine.
If the getters/setters are public anyway, then you need them to not be renamed in the minified js. That means having them use strings for names is fine - they won't be minified but that's what you wanted.
Yes, modern JS has getters/setters.
You cannot dynamically add a function which could then be compiled (and minified/obfuscated) by the Closure Compiler because that dynamic "addGettersSetters" function would only be used at runtime, so the compiler has no knowledge of what it could be creating. The downside of using the compiler is a lot of duplicate pre-compiled code, but the benefit is that the majority of the places where your getters and setters are used will either be minified or just changed to inline references to the variables.
Also, by putting in explicit getters/setters and properly annotating them with JsDoc annotations:
/*
* Set name.
* #param {string} name
*/
Layer.prototype.setName = function(name) {
this.attrs.name = name;
}
you can add some level of type safety to your code to ensure you get a warning during compilation if someone calls "setName(5)".
Otherwise I would follow Chris's suggestion and look into JS getters / setters (other reference here). I have not used these with the closure compiler though so I cannot vouch for them.
Sorry, I don't get the ne8il answer and why it was marked as the correct one.
You can do what you want by just adding .prototype between obj and [ like this:
function addGettersSetters(obj, property) {
// You can also add this if you don't want to declare attrs = {} each time
// if (!("attrs" in obj.prototype)) obj.prototype.attrs = {};
obj.prototype['get'+property] = function() { return this.attrs[property] }
obj.prototype['set'+property] = function(val) { this.attrs[property] = val }
}
And also writing the property name with capital letter. Then you can use it like this:
var Layer = function() { this.attrs = {}; };
// Or just: 'var Layer = function(){};' if you use the line commented above
addGettersSetters(Layer, 'Name');
var layer = new Layer();
layer.setName("John");
alert(layer.getName()); // "John"
Not a complete answer of the original question, just adding some info.
You can see how various JavaScript OOP frameworks handle getters/setters e.g. here: jsPerf.com - JavaScript Object Oriented Libraries Benchmark with getters and setters
is there a way for me to fully and properly define the interface without cluttering up my code?
Tan Nhu (original author of the benchmark) created his own OOP library jsface which is available at: https://github.com/tnhu/jsface
I like it, I use it for exactly this reason
EDIT: how are the getters/setters generator solved in TypeScript is mentioned e.g. in SO article get and set in TypeScript
For more complete list of other frameworks and their way of encoding getters/setters you can check List of languages that compile to JS · jashkenas/coffeescript Wiki · GitHub

custom methods and the usefulness of constructors and prototype in web-dev

ok so i know that prototype is used for inheritance and when coupled with a constructor function can be used to make custom methods. so my question here is two fold: how do i make methods for pre-built JavaScript objects like integers,strings,arrays,etc...
the other question is besides making my own methods what is the usefulness of constructors/prototype in everyday web development(i.e. creating websites) or is this more so for high-end development like making a web app or developing with new tech(i.e. html5 canvas or three.js) i haven't seen an example anywhere on the web of this being used in an everyday situation.
To create a Javascript method to an already existing object, you can simple add it to its constructor's prototype:
String.prototype.firstLetter = function() { return this.charAt(0); }
var myStr = "Cool str!";
alert(myStr.firstLetter()); // 'C'
As for how useful it will be, depends on what you do with Javascript. If you write client-side code and you need to modify an existing component, monkey-patching a function may be useful there. If you need some structure on your code (and you do), creating an object to represent the interface state may be useful.
Also, knowing how to use a tool usually avoids self-harm. =)
If you are interested, you may want to take a look into Crockford's page or buy his Javascript: The Good Parts book.
There is a lot of confusion you can avoid if you get to know the language, and you may even get to like it and find out you can do a lot of useful stuff in it.
Here's an example that extends Number:
Number.prototype.between = function(a, b) {
return this >= a && this <= b
}
var num = 0;
if (num.between(0,0)) alert('is between')
else alert('not');
Although I often use the prototype, I have not yet run across a good reason to use the constuctor property, which returns the type of an Object. W3schools.com has a good illustration of this property at http://www.w3schools.com/jsref/jsref_constructor_math.asp
You can add functions into a class's prototype:
String.prototype.report_fish = function() { alert("a fish!"); };
"".report_fish();
You can do this with numbers as well, although the syntax to invoke is slightly different:
Number.prototype.report_fish = function() { alert("a fish!"); };
(0).report_fish();
As to why you'd do this, I personally believe that you should avoid doing this to built-in objects where possible. (A persistent problem to work around when building re-usable Javascript libraries used to be and probably still is people's tendency to override and extend the Object prototype.)

When should I use my own namespace and when should I extend native js objects?

I am in the process of refactoring my code. I'm having trouble deciding on how exactly to implement a couple utility functions I have. Specifically, if certain functions are better off in my personal namespace or extending js Objects directly.
Example of extending native JavaScript Objects
(is this the proper term?).
String.prototype.prettyDate = function(){
return (this.substr(5,2) + '/' + this.substr(8) + '/' + this.substr(0,4));
}
var myString = "2010-12-27";
//logs 12/27/2010
console.log(myString.prettyDate);
Example using my own namespace
var myNamespace = (function(){
var my = {};
my.prettyDate = function ( dateStr ){
return (dateStr.substr(5,2) + '/' + dateStr.substr(8) + '/' + dateStr.substr(0,4));
}
return my;
}());
var pretifiedDate = myNamespace.prettyDate('2010-12-27');
//logs 12/27/2010
console.log(pretifiedDate);
Questions to consider
When is a utility justifiably inserted into a native JavaScript Object?
How can I tell when a utility is better off being in my own namespace?
Almost never, because of:
a/ possible conflicts with other libraries
b/ extended functions are iterated as properties by in operator, which poses problems unless filtered out by hasOwnProperty (which is not commonly used)
You can justify this for small, one-script works, but only if you 200% sure that no one, never ever will try to reuse that code somewhere. In such case use it only for functionality which spans more than one module of your code. Extending String with trim() - ok, extending String with prettyDate() - doubtful, extending Object with displayAsPageHeader() - scary.
So, almost always.
Watch this video:
http://ejohn.org/blog/building-a-javascript-library/
John Resig reckons that extending native objects is a recipe for disaster, particularly when a framework or application is likely to grow into something that does far more than was initially intended.
Unfortunately, this question doesn't have a "right" answer. It's a good discussion to have but I fear it'll be closed here. Whether native objects should be extended at all is a subjective debate, and if you accept that it's conditionally okay the answer to "when?" is "depends."
If you have control over its use and whether it will collide with other code, there's really no reason you shouldn't. It can be quite convenient and may reduce code size significantly.
Where there's a real problem with extending native objects is when you have other code running alongside your extension, which may be expecting a different extension in with the same property name, or which may be carelessly using for(var i in obj) without guarding against extensions up the prototype chain.
Ok... i'm not expert at this, but almost never!
Things you do are safer inside your namespace. And everything works fine if you follow the module pattern http://www.yuiblog.com/blog/2007/06/12/module-pattern/
However theres are some little tricks that allows us to avoid to overwrite others namespace. per example:
var myNamespace = {}; //my namespace, unsafely written
//Better solution
if(typeof myNamespace === 'undefined'){
var myNamespace = {};
}
//Shorter solution
var myNamespace = myNamespace || {};
It depends on how much control you have over what code is being run/loaded:
If it's all under your control there's nothing wrong with extending built-in objects, JavaScript is designed to be able to do this. The only problem with this is that you can have unexpected issues when two libraries change the same something. Luckily you wouldn't do this to yourself, right?
If you don't/can't know, a namespace is much safer albeit clunky and verbose. This is always safer.
Personally, I prefer the second option because I dislike overly verbose code and namespaces look funny.

Encapsulation in Javascript

I'm pretty new to Javascript, as my SO profile will attest.
I've just been reading up on a few tutorials and come across something I don't totally understand in regards to Object Orientation and Encapsulation when applied with Javascript.
The tutorial stated that Javascript objects can be declared like this:
var myCustomObject = new Object();
And that you can give it instance variables like this:
myCustomObject.myVariable = "some value";
myCustomObject.myOtherVariable = "deadbeef";
Finally, it states that you can create a template function to create new objects like this:
function CustomObject(myVariable, myOtherVariable)
{
this.myVariable = myVariable;
this.myOtherVariable = myOtherVariable;
}
I also know that you can create and assign values to variables that do not yet exist and as a result are declared implicitly, as is seen in the example, where myCustomObject didn't have a myVariable, but now it does.
So, my question is: What is there to prevent new variables from being added at some other point in the code. If I'm trying to learn how an object works and what I can/should do with it, I may never see the variable additions that could well be in some other .js file, and thus not have a full understanding of the object...
Also, how do I know that some object that has just been created won't suddently turn out to have 60 more variables added later on in code that weren't mentioned at all at creation time?
How are you meant to be able to understand what an object can contain at a glance if more can just be added to it "willy nilly"?
I can't quite believe that I'm about to quote Spiderman but …
With great power comes great responsibility
JavaScript is powerful and flexible and gives programmers lots of freedom. It doesn't come with features designed to stop programmers writing bad code. When you write JavaScript, you are responsible for making sure the code is good, not the language.
You can't, there's nothing that stops me from doing whatever I want with your objects ;) However, you don't have to use those variables..
One thing you can do is to play with scopes, example:
function myConstructor()
{
var myState = {}; //Create new, empty object
myState.text = "Hello World!";
this.say = function() {
alert(myState.text);
};
}
In this simple example you can store you internal variables in myState (or "var text = '';" etc) and they aren't accessible from outside since they are not members of an object, they are just private variables in your function. And, as you can see, the function say still has access to it.
Short answer: Absolutely nothing.
Long answer:
Javascript is a dynamic language in more ways than just the type system. Every object like thing in the language is basically an associative array which can be added to as you please. Variables (which can obviously contain these object like things) exist only within their function scope.
You can use this point to simulate private members which can tame the situation somewhat. I've posted examples of this several times before so I'll just refer you to the definitive guide on the subject: http://javascript.crockford.com/private.html.
As far as adding new members to objects in a way you did not intend goes, there's really nothing to be done that's just the way the language is.
Afterthought:
When approaching javascript try to remember it's really not an OOP language it's a weird and wonderful mix of functional / prototypical with a few OOP ideas. Don't be fooled by the java like syntax, you'll have a much better time if you play to the languages strengths rather than ape java.
Javascript objects are transformers (TM), they can turn from one form to another.
In practise this only happens to enrich objects, never to cause harm. It allows one to for example upgrade an existing 'class' rather then subclassing or to decorate instances again removing the need to create even more 'classes'. Take the following example:
var Vehicle = function(){}
var factory = {
create: function(name, props){
var v = new Vehicle();
v.type = name;
for(var prop in props) {
v[prop] = props[prop];
}
}
}
var bike = factory.create('Bike', {
wheels: 2
});
var car = factory.create('Car', {
wheels: 4,
doors: 5,
gear: 'automatic'
});
var plane = factory.create('Airplane', {
wings: 2,
engines: 4
});
Imagine what the code above would take without dynamic objects and you couldn't do this:
// lets paint our car
car.color = 'candy red';
// bling!
car.racingStripes = true;
car.mirrorDice = true;
car.furryChairs = true;
You get to enrich/personalize objects in a much easier way.

Categories

Resources