HI Mark,
The fix of allowing primitive Reference base type is ok for
implementations such as SpiderMonkey, which already does this for the
built-in methods on String.prototype, Number.prototype, and
Boolean.prototype to avoid the overhead of wrappers when calling
native methods on string, number, and boolean primitive values.
Practical implementations do not use anything like a Reference type,
instead specializing lvalue and rvalue contexts to preserve reference
bases in VM registers.
FWIW, this is what ES4 did too. Types string and String shared a
prototype object; calls on a primitive |this| to methods inherited
from the shared prototype entailed no coercion or wrapping. ES4 did
not use Reference internal types with non-primitive bases to specify
this binding. So the fix is harmonious from the start.
On Jan 8, 2009, at 7:43 PM, Mark S. Miller wrote:
We'd change the spec of GetValue and delete to do a ToObject() on
its base in order to look up the property. However, this coercion of
the base is ephemeral. The wrapper cannot escape, and ToObject has
no observable side effects, so it is just an explanatory device
equivalent to saying: "If the base is a string, we lookup the
property on String.prototype. If it's a number, ..."
In the face of multiple global objects, the spec must say *which*
original value of String, e.g., is used, or really, how the right
global object is found. It should be found by following the scope
chain to the last object, the global for the currently active code
(not the same as the global for the caller or grand caller or top
level script that's being evaluated).
Web browser embedding example:
* Window A script source:
String.prototype.trim = function () { return this.replace(/^\s*(\S*)\s*
$/, "$1"); }
function wraptrim(s) { return s.trim(); }
* Window B script source (assume window A is denoted by winA here):
alert(winA.wraptrim(" hello "));
Ok, what it there is no inherited accessor? In ES3.1-nonstrict, this
should remain a no op. However, there are two equivalent means of
explaining this no op behavior: 1) mutating an unobservable wrapper,
or 2) a failed assignment. Recall that nonstrict failed assignments
are silent, so either explanation suffices. However, if we use
explanation #2, we give ourselves license to have this fail with a
thrown error in strict code.
A strict error for attempting to set an ad-hoc property could be
helpful. All else equal, when using primitives and objects
interchangeably in generic code, the silent case is less likely to be
helpful in my experience.
Generic programming with primtiives more often wants to *read*
undefined when getting a non-existent property, and "object detect"
without having to try/catch. This common use case is not served by
strict mode in ES3.1, right? You'd have to change code to try/catch
around such probes.
/be
_______________________________________________
Es-discuss mailing list
[email protected]
https://mail.mozilla.org/listinfo/es-discuss