kangax said:
Richard said:
kangax said:
1.Examine the Variable object to see if it has a property named
"Array"; it does not.
2 Examine the Variable object to see if it has a [[Prototype]],
it does not, so move on to the next object on the scope
chain, which is the global object.
If we're talking about function code, where Variable Object is
an Activation Object, how do we know that it has no [[Prototype]]?
See below.
Possibly because of the absence of any assignment to [[Prototype]] in
association with the creation of the activation object, when every
other object creation (that I can think of right now) either specifies
a [[Prototype]] value/assignment or implies it (as in the use of "as
if by the expression new Object()").
Fair enough.
Isn't Activation Object just a specification mechanism, with
unspecified [[Prototype]]?
Yes, but the activation object becomes the function call's Variable
object and if it did have a [[Prototype]] then that would always be
involved in Identifier resolution from within a function.
Of course.
We can actually test if Activation Object has [[Prototype]] referencing
something like `Object.prototype` (or `Array.prototype`, etc.). However,
[[Prototype]] can also reference some "internal" entity, which we have
no way of checking for (and its existence probably doesn't really matter).
And if the activation object has no property, scope chain and identifier
resolution takes to global object, which is a split object, which may
have Object.prototype on the scope chain (that is implementation-
dependent).
| The values of the [[Prototype]] and [[Class]] properties of the global
| object are implementation-dependent.
Interesting example Leithead posted up on whatwg, calling -
hasOwnProperty - on global object, a WindowProxy, yet expecting the
result to be based off global object itself.
Extra interesting is Blackberry9000 bug of resolving an Object.prototype
property on the Variable object.
We can test this by setting something in containing scope and see if the
identifier is resolved off global object.
http://github.com/GarrettS/ape-javascript-library/blob/master/adhoctest/activationo.html
(can be run using gitHubSource bookmarklet)
Example source:
<!doctype html>
<html>
<head>
<title>test activation object</title>
</head>
<body style="white-space: pre">
<script type="text/javascript">
var hasOwnProperty = 12;
this.hasOwnProperty = 14;
this.gProp = "g";
(function(){
function hasOwnProperty(a){return 1;}
var constructor = 123;
function toString() { return "local"; }
function testThis(){
document.write([
hasOwnProperty("gProp"),
constructor,
toString(),
this.toString()]);
}
return testThis;
})()();
</script>
</body>
</html>
Expected output would be something* like:
1,123,local,[object Window]
* "[object Window]" is not an expectation; everything else is.
Blackberry9000/9500:
true, function Object() { [native code for Object.Object, arity=1] }
,[object Window],[object Window]
The result of first hasOwnProperty("gProp") could be explained by
the identifier being resolved on activation object's scope chain and
calling hasOwnProperty using |null| as the |this| value for the function
call, as in s10.1.6.
| When the call operation is applied to a Reference value whose base
| object is an activation object, null is used as the this value of the
| call.
The implication this has is that any identifier name that coincides with
with an Object.prototype property will not be found on the enclosing
scope. Don't name you function "hasOwnProperty", etc.
Function decompilation that expects "[native code]" will fail.
(Function decompilation is best avoided altogether, for various other
reasons).