views:

83

answers:

4

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"?

+6  A: 

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.

David Dorward
When you write *anything*, you are responsible for making sure the code is good, not the language. (At least IMHO).
annakata
That's true, but some languages take steps to try to protect programmers from themselves.
David Dorward
+2  A: 

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.

Ollie Edwards
+2  A: 

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.

Onkelborg
Just a note, be aware that this can cause some unexpected problems in case you want to extend your class later since it's impossible to access those internal variables from the outside ;)
Onkelborg
+1  A: 

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.

BGerrissen
But without exceedingly good documentation, it's possible I could never know that a car has furry chairs (love it) unless I stumble across the piece of code that declares it as so. Correct?
Jasarien
True, thats why one has to code wisely ;) Decorators are just as useful in javascript as in any other OO language. Thing is, it's easier and faster to write a decorator in JavaScript due to dynamic objects. Any fears you might have about dynamic objects are irrational unless you let dumb or malicious programmers near your code.
BGerrissen