view core-javascript/solution-2.rst @ 213:0ea90a1819c2 default tip

Custom theming
author Radomir Dopieralski <radomir.dopieralski@allegro.pl>
date Wed, 27 Jun 2012 16:35:54 +0200
parents 6c98b9680b2a
children
line wrap: on
line source

Solution two
============

Here's the code we are studying.  The first task is make a loop that
does the assignments.

.. literalinclude:: /core-javascript-work/exercise-2.js
   :language: javascript


Making a loop
-------------

As previously hinted, we use item access rather than attribute access.
The problem with attribute access is that the name of the key is
hard-coded and we want it to vary during the loop.

Here's the solution.  There's a bit of overhead in setting up the
loop, but the body of the loop is straightforward.

.. literalinclude:: /core-javascript-work/solution-2-a.js
   :language: javascript


Factory function
----------------

The second task is to write a factory function that takes the list of
keys as a parameter.

This is a common refactoring pattern, and so is worth learning well.
First we give the code, and then the explanation.

.. literalinclude:: /core-javascript-work/solution-2-b.js
   :language: javascript


Here's what we've done.  We created a wrapper function, with *keys* as
its only parameter.  This will be our factory function.  We've placed
the original function into the body of the wrapper, and return it (as
the value of the wrapper function).  Finally, we clean up by removing
the *keys* constant from the inner function.

There, it's done!  When the factory function executes it returns an
instance of the inner function for which *keys* is the argument we
supplied to the factory.


A prototype class
-----------------

The third task is to write a Fields class that has a copy_attributes
method.

Here's a function prototype based solution.  It relies on the user of
the class supplying the *new* operator to create the new instance (and
chaos results if the user forgets).

.. literalinclude:: /core-javascript-work/solution-2-c.js
   :language: javascript

A minor point is the trailing sequence of right curly braces.  Two are
followed by a semicolon, but the middle one is not.  Why?  What
happens if we put a semicolon there?


A SimpleClass solution
----------------------

Here's another solution to the third task, which does not require the
user to supply a *new* operator when creating instances.  Instead it
uses a factory function, which we call *Class* , that creates an
instance constructor function from a prototype object.

.. literalinclude:: /core-javascript-work/solution-2-d.js
   :language: javascript


Exercise: write test
--------------------

Here's an exercise.  Write a JavaScript file that tests this solution.


Exercise: bound method class
----------------------------


Recall that this-based instance methods are somewhat fragile.  In
other words, code like this will fail (and make unwanted changes to
the global object):

.. code-block:: javascript

   var instance = MyClass(arg1, arg2);

   var fn = instance.method;
   element.onclick(fn);

Let's say that a class *has bound methods* if we can safely pass
around instance methods.  In other words, we want *instance.method* to
have no dependence on the value of *this*.

We can achieve this by using a different class factory function.

.. code-block:: javascript

   var myclass = {}    // The prototype object.
   // Add methods to myclass.
   var MyClass = BoundMethodClass(myclass);

The exercise is to create (and test) a BoundMethodClass factory.