view source/objects.rst @ 201:b6864a86e876 default tip

Przetłumaczone getting-started
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sun, 15 Jul 2012 13:27:27 +0200
parents 454054afcc0a
children
line wrap: on
line source

Objects
=======

JavaScript and Python have rather different object models and here we
give a broad view of the differences.  The simplest way to create a
JavaScript object **jso** is to write:

.. code-block:: javascript

   jso = {}


The closest builtin equivalent to jso in Python is the dictionary such
as **pyo**, which is created using:

.. code-block:: python
  
   pyo = {}


The two objects jso and pyo have important similarities and
differences (mostly differences).


Late news
---------

Not incorporated in this document is a recent discovery, that 

    **JavaScript objects are like Python classes with custom item
    methods (on the metaclass) that are never instantiated.**

I've put this material in a page on :doc:`javascript-objects`.


Similarities
------------

Both objects can be used to store data.  Here's a lightly edited
command line session (using the SpiderMonkey JavaScript interpreter):

.. code-block:: javascript

   js> jso = {}
   js> jso['A'] = 'apple'
   js> jso['A']
   apple


Here's the corresponding Python session (with *sys.ps1 = 'py> '*):

.. code-block:: python

   py> pyo = {}
   py> pyo['A'] = 'apple'
   py> pyo['A']
   'apple'

In the examples above *A* is the **key** and **apple** is the value.
In both cases we are able to store values against keys.  In both cases
the value can be any object.  In most other respects, jso and pyo are
different.

Differences
-----------

Keys
^^^^

In JavaScript all keys are converted to strings.

.. code-block:: javascript

   js> jso = {}
   js> jso['1'] = 'one'
   js> jso[1]
   one

Here's an even more surprising example:

.. code-block:: javascript

   js> jso = {}
   js> a = {} ; b = {};
   js> jso[a] = 'apple'
   apple
   js> jso[b]
   apple


What's going on here?  Well, objects *a* and *b* are converted to
strings, and they have the same string representation, namely *[object
Object]*.  (We'll see later how we can change this.)  So let's try
this out (continuing the previous example):

.. code-block:: javascript

   js> jso['[object Object]']
   apple

Here, for comparison, is what happens with Python:

.. code-block:: python

   py> pyo = {}
   py> pyo['1'] = 'one'
   py> pyo[1]
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   KeyError: 1
   py> a = {}; b = {}
   py> pyo[a] = 'apple'
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   TypeError: unhashable type: 'dict'



Here JavaScript, faced with input of the wrong type, has converted it
to the required type, which is a string.

.. note::

   In JavaScript anything can be a key, and all keys are converted to
   strings before lookup.  In Python, keys are unchanged, and have to
   be hashable.

.. note::

   Python built-in objects throw an error when given incorrect input.
   JavaScript converts the input to something that might work.

.. _object-missing-keys:

Missing keys
^^^^^^^^^^^^
The notation *a[b]* is called **indexing**.  In Python, indexing with
a key that is not present in the dictionary raises an exception.

.. code-block:: python

   py> pyo = {}
   py> pyo['dne']
   Traceback (most recent call last):
     File "<stdin>", line 1, in <module>
   KeyError: 'dne'


In JavaScript, we get *undefined*, which is a special JavaScript
object (which is diferent from the *null* JavaScript object).

.. code-block:: javascript
   
   js> jso = {}
   [object Object]
   js> jso['dne']
   js> jso['dne'] === undefined
   true

(SpiderMonkey does not echo *undefined* at the command prompt, just as
Python does not echo *None*.  Therefore we use equality to show that
we truly get undefined.)

.. note::

   In JavaScript you won't get a KeyError (or IndexError).  Instead,
   you get **undefined**.

In practice, JavaScript left to itself rarely throws an error.  It
most commonly happens with code such as

.. code-block: javascript
   
   obj_a.method(args)
   obj_b.name

where respectively *obj_a.method* and *obj_name* are undefined.


Attributes
^^^^^^^^^^

In JavaScript an object has a single set of properties, which can be
accessed both by indexing and as attributes.  Here is an example:

.. code-block:: javascript

   js> jso = {}
   js> jso['a'] = 'apple'
   js> jso.a
   apple
   js> jso.b = 'banana'
   banana
   js> jso['b']
   banana

In Python a dictionary has a set of key-value pairs and in addition it
has dictionary attributes, which are methods.


.. note::

   In JavaScript the three statements below are completely equivalent
   (except for assignment to *tmp* as a side effect).

   .. code-block:: javascript

      x = a.b
      x = a['b']
      tmp = 'b'; x = a[tmp]
      
   In addition, when *a.b* is a function then
 
   .. code-block:: javascript

      x = a.b(arg1, arg2, arg3)
      tmp = 'b'; x = a[tmp](arg1, arg2, arg3)

   are equivalent.
        
   But note also that 

   .. code-block:: javascript

      x = a.b(arg1, arg2, arg3)
      tmp = a.b; x = tmp(arg1, arg2, arg3
     
   are sometimes completely different.