<?xml version="1.0" encoding="UTF-8"?>
<page>
  <body>This article is an introduction to JavaScript for those who already know Ruby. Its focus is mostly on the differences between the two. JavaScript and Ruby are very similar in many respects, but they're also very different in some areas. Both languages are highly dynamic, allowing you to change objects and methods at runtime. Both languages are very object-oriented, but with different approaches. Ruby is a class-based, object-oriented language with functional aspects while JavaScript is a functional, object-oriented language with some class-like functionality.

h3. Objects and types

While both Ruby and JavaScript have the _object_ as the most important part of the language, there are some differences in how they use objects.

Ruby and JavaScript are both dynamically typed and often employ what is known in the Ruby world as _duck typing_ instead of checking for certain types. We don't care what type the object is, just that it knows how to do what we want it to do.

[ruby]
#Ruby
animal.bark if animal.respond_to?(:bark)
[/ruby]

[javascript]
//JavaScript
if (typeof animal.bark === 'function') { animal.bark(); }
//Alternatively (short-curcuiting)
animal.bark &amp;&amp; animal.bark();
[/javascript]

However, while Ruby is _strongly typed_, JavaScript is _weakly typed_. This means that JavaScript does _implicit conversion_ of types where Ruby would throw an exception. This is usually not a problem as long as you're aware of it and know how the conversion works.

[ruby]
#Ruby
puts &quot;1&quot; + 2 # Raises TypeError
[/ruby]

[javascript]
//JavaScript
print(&quot;1&quot; + 2); // prints &quot;12&quot;
[/javascript]

Ruby prides itself in that everything in it is an object. This is not the case in JavaScript; there are a few basic types that are not objects:

* Numbers: @42@, @3.14@ - There is only one type of number, which encompasses both of what we know in Ruby as @Fixnum@ and @Float@.
* Booleans: @true@, @false@
* Empty value: @null@ - This is the equivalent of Ruby's @nil@.
* Undefined value: @undefined@ - This has no Ruby equivalent. It is used for undefined function parameters and object properties. Ruby uses @nil@ in similar situations.

That these values are not objects in the OOP sense of the word does not matter much, in my experience. In the Ruby world, we like to brag about being able to add methods to @NilClass@ or @Fixnum@, but in the real world that doesn't have much use.

In addition to these basic types, JavaScript has a few basic literals for object types, that are almost exactly the same as their equivalents in Ruby:

* String: @&quot;Hello&quot;@, @'world'@ - There is no difference between single and double quotes, and strings are immutable.
* Array: @[1, 2.3, &quot;string&quot;, ['another', 'array']]@
* RegExp: @/foo|bar/@

There is one more to add to this list, but I will wait until after the next section to cover it.

h4. Truthiness

In Ruby, only @false@ and @nil@ are false. JavaScript, like many other languages, has the concept of _truthiness_, where values are either true or false depending on what they contain. This is a form of implicit conversion, and the following values are falsy:

* @0@ - The number zero.
* @&quot;&quot;@ - The empty string.
* @NaN@ - A special value meaning Not a Number. If you do things like @0/0@ you will get this value.
* @null@ - The empty value.
* @undefined@ - The undefined value.

Anything else is &quot;truthy&quot;. You can convert any truthy or falsy value into true or false by using a double _not_ operator:

[javascript]
!!0 //false
!!1 //true
[/javascript]

h3. Variables

Variables in JavaScript, like Ruby, hold data. In the case of basic types, they hold the value of the type itself, but in the case of objects it holds a _reference_ to the object itself. This is similar to Ruby's notion of references and _immediate values_ with the only difference that the latter group are not real objects in JavaScript.

Variables in JavaScript are declared with the @var@ keyword:

[javascript]
var myString = &quot;Hello, universe&quot;
[/javascript]

As JavaScript is not staticly typed there is no need to declare the type of the variable. The @var@ keyword only tells JavaScript that the following is a variable. _Always_ use @var@ when declaring a new variable. It will seem to work well without it, but what's really happening is that the variable will be created in the _global scope_, and we all know that *global variables are evil*. It is conventional in JavaScript to use camelCased identifiers when you need to use more than one word. The first part (word) of an identifier is in all lowercase except for one case which we'll cover later. You can declare a variable without explicitly giving it a value. The value will then be @undefined@.

h3. The object

JavaScript, like Ruby, is heavily object-oriented, and objects are used everywhere. Remember a few lines up where I said there was another literal to add to the list in addition to strings and arrays? Well, that missing literal is the _object literal_, and it's one of those things that makes JavaScript what it is. It means that you can effortlessly create objects whenever you need them, pass them around and manipulate them at will. The syntax for creating an object is:

[javascript]
{ propertyOne: 'a string', propertyTwo: ['an', 'array'] }
[/javascript]

Does it remind you of something? Yes, of course, it looks just like a Ruby @Hash@! And that's basically just what it is. Objects in JavaScript are _hash maps_. An object can have anything attached to it with the use of a string key. If you already have an object, and would like to add or change a property on it, there are two ways of doing that. The first will look very familiar:

[javascript]
var myObject = {};
myObject['foo'] = 'bar';
[/javascript]

The second will also look familiar, but does not work in the same way as in Ruby:

[javascript]
myObject.foo = 'baz';
[/javascript]

In JavaScript, the bracket notation and the dot notation are exactly the same. They just add (or change) a property to an object. In Ruby, we disguise methods as properties, so

[javascript]
my_object.foo = 'bar';
[/javascript]

is really

[javascript]
my_object.foo=('bar');
[/javascript]

In JavaScript this works the other way; methods are properties of an object.

h3. Functions

JavaScript is a functional language. This means that functions play a major role along with objects. In fact, functions _are_ objects, but let's not get into that just yet. More important is the fact that functions are _first class citizens_. You can assign them to variables and pass them around like any other object. There are a couple of ways to define a function:

[javascript]
function myFunction (foo, bar) {
  print(foo + bar);
};
[/javascript]

This is the same as:

[javascript]
var myFunction = function (foo, bar) {
  print(foo + bar);
}
[/javascript]

Because functions in JavaScript are first-class citizens, parentheses are not optional when invoking them. Using the name of a function without parentheses will return the _function object_ itself instead of executing it and returning the result.

[javascript]
print(myFunction); //Will print a string representation of the function
print(myFunction('hello', 'world')); //Will print &quot;helloworld&quot;
[/javascript]

h4. Methods

Functions, like anything else, can be attached to an object. When this happens, they are usually referred to as _methods_. JavaScript has a @this@ keyword, which corresponds to Ruby's @self@. When inside a method, @this@ refers to the object to which the method belongs. More accurately, it refers to the _message receiver_ in OO terminology. This matters because a function can be attached to more than one object, so the context in which it is executed matters.

[javascript]
var horse1 = {name: 'Fearless Flames'};
var horse2 = {name: 'Silver Wind'};
var myFunction = function(){ return this.name; };

horse1.getName = myFunction; //No (), we're passing the function itself
horse2.getName = myFunction;

print(horse1.getName()); //Prints &quot;Fearless Flames&quot;
print(horse2.getName()); //Prints &quot;Silver Wind&quot;
[/javascript]

h4. Parameters and return values

JavaScript functions have implicit return values, but not in the same way that Ruby's methods do. If you omit the @return@ statement in a function, this is the same as ending the function with a simple @return;@ which will return @undefined@. This is fine for functions that don't need to return a value, but another thing in JavaScript that is optional is the semicolon to end an expression. You can omit this, like in Ruby, but it's not recommended because it can cause problems. The JavaScript interpreter actually inserts semicolons where it sees fit, and this isn't always where you would put them.

In Ruby methods we can have special parameters called _splats_ and _blocks_. Splats collect 0 or more arguments into an array while block parameters contain the method's associated _block_ as a @Proc@ variable. The reason for having the splat operator in Ruby is that a method with 3 parameters must be passed 3 arguments, or Ruby will throw an @ArgumentError@. JavaScript doesn't enforce the number of arguments passed to a function, so you can pass as many or as few you want. Within the function definition, there exists a special _array-like_ (it's not really an array) variable which contains all the arguments passed in to it. Its name is simply @arguments@.

[javascript]
function joinStrings () {
  var joinedString = &quot;&quot;;
  for (var i = 0; i &lt; arguments.length; i++) {
    string = string + arguments[i];
  }
  return joinedString;
};
[/javascript]

h4. Anonymous functions and closures

JavaScript doesn't have the concept of _blocks_ that Ruby does. The reason is because it simply doesn't need them, and the reason it doesn't need them is because it has _anonymous functions_, also called _lambdas_. To create an anonymous function, just use the function operator without providing a name for the function:

[javascript]
function(){ print(&quot;Hello from anynymous function!&quot;); }
[/javascript]

Of course, the above function will never be executed, because we can't reference it. One way we can use anonymous functions and reference them is to pass them as arguments to another function, in effect the same as blocks in Ruby:

[javascript]
var map = function(array, iteratorFunction){
  var result = [],
      i;
  for (i = 0; i &lt; array.length; i++) {
    result.push(iteratorFunction(array[i]));
  }
  return result;
};

var array = [1,2,3,4,5];
var arrayPlus1 = map(array, function(n){ return n+1; });
[/javascript]

Functions in JavaScript, like blocks in Ruby, provide _closure_. That is, the variables available in the scope where the function is defined are always available in the function, even if it's called from another scope.

[javascript]
function makeCounter () {
  var count = 0;
  return function(){
    return count++;
  };
};

var counter1 = makeCounter();
var counter2 = makeCounter();
print(counter1()); // Prints 0
print(counter1()); // Prints 1
print(counter2()); // Prints 0
[/javascript]

h4. Functions as scope

In JavaScript, the only construct which provides _scope_ is the function. This means that for and while loops, for example, do not have their own scope. This is the same in Ruby, but while Ruby has classes and modules to provide shelter from the global scope, JavaScript doesn't have anything like that. But we can exploit the fact that functions have their own scope to achieve the same.

[javascript]
var myObject = (function(){
  //These variables are only available inside the anonymous function
  var foo = 'bar';
  var bar = 'baz'; //But don't forget the &quot;var&quot;!
  var foobar = foo + bar;
  
  //This object will be returned and assigned to myObject
  return {
    barfoo: foobar;
  };
})(); //We're calling the anonymous function right away
[/javascript]

This example is contrived, but this pattern of defining an anonymous function and immediately calling it is very useful for creating scope whenever you want to work with some variables without polluting the existing scope.

h4. Objects for namespacing

We can take this further and use objects to create a namespace for our stuff. We do this simply by creating one global object which will contain all of our objects as properties:

[javascript]
var MyModule = {};
MyModule.foo = 'bar';
[/javascript]

We can combine this with the anonymous function to provide both namespacing and scope:

[javascript]
MyModule.myObject = (function(){
  var privateVar = 'foo';
  var privateFunction = function(){
    return privateVar.toUpperCase();
  };
  
  return {
    foo: function(){ //Closure
      return privateFunction();
    };
  };
})();

MyModule.myObject.foo(); //Returns &quot;FOO&quot;
[/javascript]

This pattern is called the &quot;module pattern&quot;:http://yuiblog.com/blog/2007/06/12/module-pattern/.

h4. @call@ and @apply@

Two interesting methods that every function in JavaScript has are @call@ and @apply@. These methods allow you to call a function while setting what the @this@ keyword should point to inside that function.

[javascript]
var printName = function(){
  print(this.name);
};

var horse = {name: 'Dapple Apple'};
printName.call(horse); // Prints &quot;Dapple Apple&quot;
[/javascript]

The difference between @call@ and @apply@ is the way arguments are passed on to the function. With @call@, you give it the arguments like you would when calling it directly, but with @apply@ you pass the arguments as an array (or the @arguments@ array from the current function).

[javascript]
myFunction.call(object, var1, var2);
myFunction.apply(object, [var1, var2]);
[/javascript]

The @apply@ version is kind of similar to _splatting_ an array in a similar situation in Ruby:

[ruby]
object.myMethod(*an_array)
[/ruby]

h3. Prototypal inheritance

Ruby is a class-based object-oriented language, where classes inherit other classes. In JavaScript, on the other hand, objects inherit directly from other objects. Every object in JavaScript contains a (secret) link to the object from which it inherits. The inherited object is called the prototype, hence the term prototype-based inheritance. When you try to access a property on an object and that object doesn't have the property, the object's prototype is searched, then the prototype's prototype and so on until you reach @Object.prototype@, which is the endpoint for this search from all objects. That is, all objects inherit from the @Object.prototype@ object, directly or indirectly. To create a new object based on an existing object, you use the @object@ function:

[javascript]
var oldObject = {foo:'bar', bar:'baz'};
var newObject = object(oldObject);
newObject.bar = 'BAZ';
newObject.baz = 'QUUX';

print(newObject.foo); // Prints &quot;bar&quot;, from oldObject
print(newObject.bar); // Prints &quot;BAZ&quot;, newObject.bar &quot;overrides&quot; oldObject.bar
print(newObject.baz); // Prints &quot;QUUX&quot;, from newObject
[/javascript]

The @object@ function doesn't actually exist in JavaScript, but it's easy to create. 

[javascript]
function object (o) {
  function F(){};
  F.prototype = o;
  return new F();
};
[/javascript]

To explain how this function works we have to take a look at..

h3. Classes

Classes? Yes, even though JavaScript is prototype-based, it has the concept of classes. Kind of. There is a @new@ keyword which is very familiar to those having used class-based languages. In Ruby this is not a keyword, but a _class method_, but the concept is the same: It instantiates a new object from that class. But what does @new@ do in JavaScript?

Every function in JavaScript has a @prototype@ property (functions are objects, remember?). When a function is called with the @new@ keyword, this function becomes a _constructor_. What this means is that when the constructor is called (with @new@), a new object is created, whose (secret) prototype link points to that function's @prototype@ property. This new object is also the default return value of the constructor function. So, in effect, the object returned by a constructor inherits the constructor's @prototype@ property. While in the constructor function, the @this@ keyword refers to this new object.

The @prototype@ property should not be confused with the property which links to an object's actual prototype, or &quot;ancestor&quot;. The @prototype@ property, despite its name, is just another property and only has special meaning for function objects. The _real_ prototype of an object is hidden in most implementations. Mozilla _does_ reveal this link through the property @__proto__@, so if it helps make things clearer, you can think of it by that name to avoid confusion with @prototype@.

[javascript]
var Horse = function(name){
  this.name = name;
};

Horse.prototype.getName = function(){
  return this.name;
};

var myHorse = new Horse('Touch of Frost');
var myOtherHorse = new Horse('Westerly Winds');

print(myHorse.name); // Prints &quot;Touch of Frost&quot;
print(myOtherHorse.getName()); // Prints &quot;Westerly Winds&quot;
[/javascript]

By convention, constructor functions start with an uppercase letter, unlike normal functions or methods. This is to easily distinguish between the two, because you don't want to call normal functions with the @new@ keyword and you don't want to call constructors without it.

In the example above, two Horses are &quot;instantiated&quot;. They each get their own name, and the names are printed. The first horse's name is accessed directly with the @name@ property. This property is defined directly on the object in the constructor. The second horse's name is accessed through a getter method. This method (@getName@) is defined on Horse.prototype, so when we try to access @myOtherHorse.getName@, JavaScript can't find the @getName@ property on @myOtherHorse@, so it searches its secret link, which points to @Horse.prototype@, and finds the method there. Because @this@ in a method definition points to the _message receiver_ (that is, @myOtherHorse@), we can access @this.name@ and return it.

If we define a new method @getName@ directly on either of our horses, this will take precedence over the one defined on @Horse.prototype@ because of the way prototypal inheritance works. It is the same as defining a _singleton method_ on an object in Ruby.

So, now we know enough to be able to explain what the @object@ function we defined in the last section does. Since JavaScript doesn't provide this function and we can't edit the actual prototype link for an object, we have to jump through some hoops to create it ourselves. Let's have a look at it again..

[javascript]
function object (o) {
  function F(){};
  F.prototype = o;
  return new F();
};
[/javascript]

Firstly, we create a function @F@, which because of the function scope, is private to @object@. Then we set @F.prototype@ to point to the object which was passed in, @o@. This is the object we want the new object to inherit from. Lastly, we return the result of calling @F@ with the @new@ keyword. This creates a new object and points its prototype link to @o@. Mission accomplished.

h3. Extending the default toolset

In Ruby, classes are &quot;open&quot; and you can extend any class with new methods. This is also the case for JavaScript. To extend a class in JavaScript, we just add the property to the constructor's @prototype@:

[javascript]
String.prototype.trim = function(){
  return this.replace(/^\s+|\s+$/g, '');
};

&quot;  hello  &quot;.trim() // &quot;hello&quot;
[/javascript]

There are, however, some gotchas with doing this. The most important has to do with @Object.prototype@. Properties added to this object will be available to _every object_. This in itself is not really a problem. The problem lies with the way we iterate through an object's properties:

[javascript]
var myObject = {foo: 'bar', bar: 'baz'};
for (var p in myObject) {
  print(p + ': ' + myObject[p]); // Prints &quot;foo: bar\nbar: baz&quot;
}
[/javascript]

The @for..in@ expression will iterate through an object's properties, but it will also include all properties added to every object in its prototype chain, including @Object.prototype@. You can avoid this by checking if the property belongs to the object itself or to one of its ancestors:

[javascript]
var myObject = {foo: 'bar', bar: 'baz'};
for (var p in myObject) {
  if (myObject.hasOwnProperty(p)) {
    print(p + ': ' + myObject[p]); // Prints &quot;foo: bar\nbar: baz&quot;
  }
}
[/javascript]

This is the recommended way of iterating an object's properties, because when you write code for a shared environment like the web browser, you have no idea what other code may be used at the same time as yours. Someone may have extended @Object.prototype@, and it it could mess up your code. There also seems to be a wide conscensus that everyone should avoid extending @Object.prototype@.

For the same reason, some advocate that you shouldn't extend @Array.prototype@, but not everyone agrees with this because the only way one would have properties added to this object show up when iterating an array is when treating the array as an object by using the @for..in@ expression to iterate it:

[javascript]
var array = [1,2,3];
for (var i in array) {
  print(array[i]); //Prints &quot;1\n2\n3&quot;
}
[/javascript]

The reason this works is that arrays in JavaScript are just specialised objects. They are hash maps that only use integers (represented as strings) as keys and have some special methods and other properties to work with the values in it, like the @length@ property. The &quot;correct&quot; way of iterating an array is to use this property in a for or while loop:

[javascript]
var array = [1,2,3];
for (var i = 0; i &lt; array.length; i++) {
  print(array[i]);
}
[/javascript]

h3. Further reading

This article covers some basics, but there is much more to learn about JavaScript. Some recommended resources are:

* &quot;A (Re)-Introduction to JavaScript&quot;:https://developer.mozilla.org/en/A_re-introduction_to_JavaScript by Simon Willison
* &quot;The JavaScript Programming Language&quot;:http://video.yahoo.com/video/play?vid=cccd4aa02a3993ab06e56af731346f78.1710507 video presentations by &quot;Douglas Crockford&quot;:http://www.crockford.com/javascript/ at the &quot;YUI Theater&quot;:http://developer.yahoo.com/yui/theater/
* Mozilla Developer Center's &quot;JavaScript section&quot;:http://developer.mozilla.org/en/docs/JavaScript
* &quot;ECMA-262 Specification&quot;:http://www.ecma-international.org/publications/standards/Ecma-262.htm</body>
  <created-at type="datetime">2007-08-05T19:50:47-04:00</created-at>
  <id type="integer">12</id>
  <parent-id type="integer" nil="true"></parent-id>
  <published type="boolean">true</published>
  <slug>javascript_eye_for_the_ruby_guy</slug>
  <summary></summary>
  <title>JavaScript Eye for the Ruby Guy</title>
  <updated-at type="datetime">2009-10-16T17:33:20-04:00</updated-at>
</page>
