What is Ext.namespace, how should we use them? - javascript

I came across to Ext.namespace() in the project that I am working on.
I looked in Sencha's website and the explanation was not very helpful.
This is what they are saying:
Creates namespaces to be used for scoping variables and classes so
that they are not global. Specifying the last node of a namespace
implicitly creates all other nodes.
Ext.namespace('Company', 'Company.data');
They also mention that Ext.ns('Company.data') is preferable.
I apologize if this question seems simple or dumb, but I really want to completely understand this concept. Thanks in advance
This is what is not very clear to me:
If I have Ext.namespace('Company', 'Company.data') at the top of my JS page, does this mean that it carries all the other function name and variables (like a global scope)?
What exactly 'Company' and 'Company.data' stand for in Ext.namespace('Company', 'Company.data')?
Why new convention Ext.ns('Company.data') does not have 'Company' like in Ext.namespace?
What does this mean Specifying the last node of a namespace implicitly creates all other nodes?
When exactly this idea should be used?

First off, this is what Ext.ns('Company.data') is roughly equivalent too:
if (!Company) var Company = {};
if (!Company.Data) Company.Data = {};
Basically, it is just a shortcut for defining deeply nested structures
of objects. It is useful if your project structures this way; I've seen
projects with a Java backend that duplicate the
com.company.app.data.package package names in JavaScript, for which
Ext.ns is a nice shortcut.
Addressing your questions point by point:
If I have Ext.namespace('Company', 'Company.data') at the top of my JS page, does this mean that it carries all the other function name and variables (like a global scope)?
No. You have to add to Company.Data, like Company.Data.newVal = 5;.
What exactly 'Company' and 'Company.data' stand for in Ext.namespace('Company', 'Company.data')?
They are names, chosen by you, following your projects convention.
Why new convention Ext.ns('Company.data') does not have 'Company' like in Ext.namespace?
Because 'Company' is implied. That is, Ext.ns('Company',
'Company.data') is like:
if (!Company) var Company = {};
if (!Company) var Company = {};
if (!Company.Data) Company.Data = {};
This makes it easier to see why the first 'Company' is redundant.
What does this mean Specifying the last node of a namespace
implicitly creates all other nodes?
When exactly this idea should be used?
I answered these two above.

Ext.namespace is really only useful if you want to define your own classes without using Ext.define.
The example below requires the namespaces to be created ahead of time:
Company.data.Form = Ext.extend(...); //this is the old way of defining classes
The standard way for creating ExtJS classes is:
Ext.define('Comany.data.Form', {...});
This method creates the namespaces for you automatically.

Related

Assignment of one variable to two values?

I checked out a github project recently, and I found the following code in one of the files:
var fu = $('#fileupload').data('blueimpFileupload'),
template;
It seems like this is assigning one variable to two values. What is it actually doing? Someone in my office mentioned that it may be the equivalent of just saying:
var f = $('#some-id').data('string');
var template;
Is this the case?
Your colleague is correct: you are declaring two variables, and assigning only to the first. The two statements are equivalent.
The declaration is not uncommon, quite common in fact, its a requirement of JSLint, to have a single var , and all the variables declared at the top as it would be done by hoisting anyways (but not necesserily in a single line).
On the other hand, there's a well accepted convention for declaring the variables in separate lines, sorted alphabetically. The declaration you see is passing JSLint check and adhering to convetion

Static import in Javascript without 'with'

Context: I have written a mini JS library for myself which is simply a collection of commonly used classes. I have followed the IIFE (http://benalman.com/news/2010/11/immediately-invoked-function-expression/) technique to separate my code into modules/classes and they're all grouped under a common global namespace var. Let's call it, ns. So we have a typical setup, ns.ClassA, ns.ClassB, etc. Now on the other hand, a separate script (main.js) is loaded at runtime and appended to the document, and this main.js contains the actual code that uses these classes.
Goal: I am trying to find an elegant way of accessing the classes inside main.js directly by calling the class name instead of having to access them through ns. . For example, I would want to be able to do var a = new ClassA(); instead of var a = new ns.ClassA();
Solutions researched & considered:
1) the dreaded 'with' keyword (javascript "static imports"). In this case, I would do something like with(ns){ var a = new ClassA()} , except I will have to wrap the entire main.js inside the with(ns) statement. This is undesirable for obvious reasons.
2) using locally declared variables.
var ClassA = ns.ClassA, ClassB = ns.ClassB;
and then, I will be able to instantiate ClassA and ClassB directly. However, this approach would require me to manually maintain the declaration, and it will just get very messy and hard to maintain as the number of classes increase in the package.
3) pollute the global scope by injection
use a for loop to iterate over ns and map all the classes inside nsto global scope. This is clearly undesirable, and also it will create conflicts for cases such as ns.Event, ns.Audio etc.
4) PaperScript-style (http://paperjs.org/tutorials/getting-started/working-with-paper-js/)
Inspired by PaperScript from PaperJS, where PaperScript code is automatically executed in its own scope that without polluting with the global scope still has access to all the global browser objects and functions, such as document or window. Looking at their source code on GitHub (sorry SO won't let me post any more links), they seem to be using some custom script pre-processing and then Acorn.js to parse. The end result is that one can directly refer to any class inside the paper object. For example, var path = new Path() instead of var path = new paper.Path(), which is exactly what I wanted to achieve. However, my fear is that it might seem to be too much work to implement such a simple feature. So I wanted to see if any one has any ideas?
Thank you for taking your time to read this verbose description of the problem. Any inputs are appreciated.
Note: I have done my best in the past two days into researching this topic, please forgive me if I missed any obvious solutions. In addition, if there's no easy solution to this, I will simply stick with the ns.ClassA pattern. Thank you for your help!
I'm not an expert but I believe you could create a prototype of String and set your vars like so
String.prototype.ns = function(){
return new ns[this]();
}
var ca = "ClassA".ns();

What is the point of declaring variables without assignment?

I'm studying some CreateJS samples and in one of them I've seen this and I'm wondering what use it's for
(function() {
var c = createjs;
var a = function(blabla) {
this.blabla = blabla;
var p = Game.prototype;
p.a;
p.b;
p.c;
p.d;
/*
... 15 variables like that ...
*/
p.init = function(param) {
/* blabla */
}
/*
...
long code after that
...
*/
})();
It's on the github samples, in the /createjs/sandbox-master/PlanetaryGary directory, it's the file js/Game.js
I'm the original author of the code in question. This pattern comes down to the simple philosophy that good code is self-documenting.
It's worth a quick mention for those coming into this blind that those properties are not actually named a,b,c, etc. It's also worth mentioning that they are usually assigned a default value (though not in this particular case).
The up-front variable declarations explicitly define the fields that will be associated with the "class". This allows a developer to scan from the top down, and establish a mental model of the data the class operates on prior to looking at the methods that operate on it.
It provides a convenient, contextual place to hook doc comments, though the referenced code is not documented.
/**
* Docs for firstName here.
**/
p.firstName = "default";
/**
* lastName docs.
**/
p.lastName = "default";
Lastly, I've found it encourages a more thoughtful approach to data and documentation. The act of defining a new property becomes an opportunity to view the existing properties and evaluate the necessity of the new field. I've seen a lot of bugs and poor code result from devs appending properties to classes willy-nilly.
It's also a lot harder to forget to document new properties (and much easier to quickly spot undocumented properties) when you're explicitly defining them in a dedicated area of your code.
Without knowing too many specifics about the alphabetical data members of some Game object, mentioning p.a, p.b, etc. in the way that you have shown is a good way to expose exactly how the variable p is structured.
In the control flow of the code snippet you've shared, we can see exactly what fields the variable p has before performing any initialization or other operations on it.
It is possible that the object p has getters assigned to it with side effects:
Object.defineProperty(p, 'a', { get: function() {
window.universalConstant = 42;
return p._a;
});
Possible, but unlikely. Probably it's a misguided attempt at documentation as #PaulD suggests.

Will there be a new way of managing javascript classes?

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.

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