Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

from java to javascript: the object model

I'm trying to port an application I wrote in java to javascript (actually using coffeescript).

Now, I'm feeling lost.. what do you suggest to do to create class properties? Should I use getter/setters? I don't like to do this:

myObj.prop = "hello"

because I could use non existing properties, and it would be easy to mispell something..

How can I get javascript to be a bit more like java, with private, public final properties etc..? Any suggestion?

like image 817
luca Avatar asked Aug 23 '11 07:08

luca


People also ask

What is the JavaScript object model?

The JavaScript object model exposes properties using methods that are prepended with set_ and get_ based on the ability to retrieve or set the value of that property. The JavaScript Class Library contains reference material for objects and their properties.

Are objects in Java and JavaScript same?

JavaScript code used to run only in the browser, but now it can run on the server via Node. js. Objects of Java are class-based even we can't make any program in java without creating a class. JavaScript Objects are prototype-based.

What is a JavaScript object in Java?

The JSObject class provides a way to invoke JavaScript methods and examine JavaScript properties. Any data returned from the JavaScript engine to Java is converted to Java data types. Certain data passed to the JavaScript engine is converted to JavaScript data types.

What is object object in JavaScript?

An object is a collection of properties, and a property is an association between a name (or key) and a value. A property's value can be a function, in which case the property is known as a method. Objects in JavaScript, just as in many other programming languages, can be compared to objects in real life.


2 Answers

If you just translate your Java code into JavaScript, you're going to be constantly fighting JavaScript's object model, which is prototype-based, not class-based. There are no private properties on objects, no final properties unless you're using an ES5-compatible engine (you haven't mentioned what your target runtime environment is; browsers aren't use ES5-compatible, it'll be another couple of years), no classes at all in fact.

Instead, I recommend you thoroughly brief yourself on how object orientation actually works in JavaScript, and then build your application fully embracing how JavaScript does it. This is non-trivial, but rewarding.

Some articles that may be of use. I start with closures because really understanding closures is absolutely essential to writing JavaScript, and most "private member" solutions rely on closures. Then I refer to a couple of articles by Douglas Crockford. Crockford is required reading if you're going to work in JavaScript, even if you end up disagreeing with some of his conclusions. Then I point to a couple of articles specifically addressing doing class-like things.

  • Closures are not complicated - Me
  • Prototypical inheritance in JavaScript - Crockford
  • Private Members in JavaScript - Crockford
  • Simple, Efficient Supercalls in JavaScript - Me Includes syntactic sugar to make it easier to set up hierarchies of objects (it uses class-based terminology, but actually it's just prototypical inheritance), including calling "superclass" methods.
  • Private Members in JavaScript - Me Listing Crockford's solution and others
  • Mythical Methods - Me
  • You must remember this - Me

Addressing some of your specific questions:

what do you suggest to do to create class properties? Should I use getter/setters? I don't like to do this:

myObj.prop = "hello"

because I could use non existing properties, and it would be easy to mispell something..

I don't, I prefer using TDD to ensure that if I do have a typo, it gets revealed in testing. (A good code-completing editor will also be helpful here, though really good JavaScript code-completing editors are thin on the ground.) But you're right that getters and setters in the Java sense (methods like getFoo and setFoo) would make it more obvious when you're creating/accessing a property that you haven't defined in advance (e.g., through a typo) by causing a runtime error, calling a function that doesn't exist. (I say "in the Java sense" because JavaScript as of ES5 has a different kind of "getters" and "setters" that are transparent and wouldn't help with that.) So that's an argument for using them. If you do, you might look at using Google's Closure compiler for release builds, as it will inline them.

How can I get javascript to be a bit more like java, with private...

I've linked Crockford's article on private members, and my own which lists other ways. The very basic explanation of the Crockford model is: You use a variable in the context created by the call to your constructor function and a function created within that context (a closure) that has access to it, rather than an object property:

function Foo() {
    var bar;

    function Foo_setBar(b) {
        bar = b;
    }
    function Foo_getBar() {
        return bar;
    }

    this.setBar = Foo_setBar;
    this.getBar = Foo_getBar;
}

bar is not an object property, but the functions defined in the context with it have an enduring reference to it. This is totally fine if you're going to have a smallish number of Foo objects. If you're going to have thousands of Foo objects you might want to reconsider, because each and every Foo object has its own two functions (really genuinely different Function instances) for Foo_getBar and Foo_setBar.

You'll frequently see the above written like this:

function Foo() {
    var bar;

    this.setBar = function(b) {
        bar = b;
    };
    this.getBar = function() {
        return bar;
    };
}

Yes, it's briefer, but now the functions don't have names, and giving your functions names helps your tools help you.

How can I get javascript to be a bit more like java, with...public final properties

You can define a Java-style getter with no setter. Or if your target environment will be ES5-compliant (again, browsers aren't yet, it'll be another couple of years), you could use the new Object.defineProperty feature that allows you to set properties that cannot be written to.

But my main point is to embrace the language and environment in which you're working. Learn it well, and you'll find that different patterns apply than in Java. Both are great languages (I use them both a lot), but they work differently and lead to different solutions.

like image 129
T.J. Crowder Avatar answered Oct 07 '22 10:10

T.J. Crowder


You can use module pattern to make private properties and public accessors as one more option.

like image 39
pcjuzer Avatar answered Oct 07 '22 10:10

pcjuzer