Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In javascript, alias namespace?

Tags:

javascript

In javascript, shouldn't I alias a namespace?

In the Naming chapter of Google JavaScript Style Guide, it says:

//Do not alias namespaces.
myapp.main = function() {
  var namespace = some.long.namespace;
  namespace.MyClass.staticHelper(new namespace.MyClass());
};

But I cannot fully understand this issue. Why not alias a namespace for brevity?

like image 836
Miaonster Avatar asked Aug 01 '12 13:08

Miaonster


3 Answers

You change this, which could break functions in the aliased namespace. Example:

var foo = {
    bar: function () {
        console.log(this.baz);
    },
    baz: 42
};

foo.bar(); // prints 42
var alias = foo.bar;
alias(); // prints undefined, because `this` is no longer `foo`
like image 75
Matt Ball Avatar answered Sep 17 '22 23:09

Matt Ball


I think this rule applies to namespace objects only:

The name of a local alias should match the last part of the type.

What you should alias (see the rule one above) are the things you really want to use, in here the MyClass constructor/namespace.

Improveded code:

myapp.main = function() {
  var myClass = some.long.namespace.MyClass;
  myClass.staticHelper(new myClass());
};

Of course, this does not apply to the namespaces whose several properties you want to use. If your code had also a need for namespace.TheirClass, it would be OK.

like image 36
Bergi Avatar answered Sep 19 '22 23:09

Bergi


The document explicitly says you should alias long namespaced types locally:

Use local aliases for fully-qualified types if doing so improves readability. The name of a local alias should match the last part of the type.

However, except for reference safety I can't imagine why you shouldn't alias namespaces

The problem with an aliased namespace is that the references don't point to the same instances anymore.

my.long.namespaces.myFunc()
// this refers to the same function, but is a different reference
var myLocalNamespace = my.long.namespace;
namespace.myFunc();
// and you can easily introduce bugs which are hard to find
myLocalNamespace.myFunc = "foobar";
myLocalNamespace.myFunc()  // throws a type error because myFunc is now a string

This bug is hard to search for.

Aliasing has a lot of benefits though. Each member lookup in JavaScript costs time. So having code that constantly needs to lookup a chain of members is wasted speed. Since the cost of a local var is negligible it is strongly advised using local vars whenever you are referring to long namespaces, function results (like $("something")) and so on. Also, it makes your code much more readable. Consider the following:

var handleNamespace = function() {
    my.really.long.namespace.foo = "bar";
    my.really.long.namespace.doIt(my.really.long.namespace.foo);
    my.really.long.namespace.member = my.really.long.namespace.somethingElse(my.really.long.namespace.addOne(2));
};

As you see this gets confusing rather quickly. Getting rid of repeated code saves processing power and makes your code more readable.

var handleNamespace = function() {
    var namespace = my.really.long.namespace,
        three = namespace.addOne(2);

    namespace.foo = "bar";
    namespace.doIt(namespace.foo);
    namespace.member = namespace.somethingElse(three);
};
like image 23
Torsten Walter Avatar answered Sep 20 '22 23:09

Torsten Walter