========================================================= HASPROP: Exposed property existence check ("in" operator) ========================================================= Background ========== Property existence check is done using the ``in`` operator in ECMAScript code, e.g.:: print('foo' in bar); // check whether foo.bar exists This involves: * An expression for the left-hand-side * An expression for the right-hand-side * ``in`` semantics (E5 Section 11.8.7) * A call to ``[[HasProperty]]`` First draft =========== Starting from the property accessor, then applying ``in`` (and skipping any unused steps): 1. Call ``CheckObjectCoercible`` for the base value. In practice, throw a ``TypeError`` if the base value is ``null`` or ``undefined``. 2. If the base value is not an object, throw a ``TypeError``. 3. Coerce property name to string using ``ToString()``. 4. Call ``[[HasProperty]]`` with the base object and the coerced property name. Note that the error throwing is unconditional and happens for non-strict code too:: // throws TypeError "foo" in "bar"; More formally, suppose ``O`` is the base value, ``P`` is the property name value: 1. If ``O`` is ``null`` or ``undefined``, throw a ``TypeError`` 2. If ``O`` is not an object, throw a ``TypeError`` 3. ``P`` = ``ToString(P)`` 4. Call ``O.[[HasProperty]](P)``, and return its result The step 1 is unnecessary (step 2 suffices): 1. If ``O`` is not an object, throw a ``TypeError`` 2. ``P`` = ``ToString(P)`` 3. Call ``O.[[HasProperty]](P)``, and return its result Inlining HasProperty ==================== Inlining ``[[HasProperty]]`` from E5 Section 8.12.6: 1. If ``O`` is not an object, throw a ``TypeError`` 2. ``P`` = ``ToString(P)`` 3. Let ``desc`` be the result of calling the ``[[GetProperty]]`` internal method of ``O`` with property name ``P``. 4. If ``desc`` is ``undefined``, then return ``false``. 5. Else return ``true``.