Strict undefined this

Mark S. Miller erights at
Sat Aug 30 15:10:51 PDT 2008

On Sat, Aug 30, 2008 at 2:02 PM, Erik Arvidsson
<erik.arvidsson at> wrote:
> On Fri, Aug 29, 2008 at 22:51, Brendan Eich <brendan at> wrote:
>> #c wins by maximizing TC purity, utility, and safety.
>> /be
> d) Lexical scoping
> I thought one of the points with changing *this* in strict mode was to
> make it use lexical scoping where it "makes sense"?

I agree with all the goals you state. There was an earlier proposal,
made by Crock and agreed to before March by the overall committee
(both the 3.1 and 4 factions). It was even somewhat orthogonal to
strict-mode, and would have made the non-strict language more
intuitive as well. However, at the March meeting I presented something
like the following example which demonstrates a fatal ambiguity:

    function PointMaker() {
      this.count = 0;
      that = this;

      function Point(x, y) {
        this.x = x;
        this.y = y;
      Point.prototype.getX = function() { return this.x; }
      Point.prototype.setX = function(x) { this.x = x; }

      this.Point = Point;

// Each PointMaker is a factory for new points that counts how many
points it made:
var pointMaker = new PointMaker();

foo(new (pointMaker.Point)(3,5));

// How many has it made so far?
print(pointMaker.count); // 1

If foo() only uses the point it's been given in the expected ways, all
is cool. But what if foo() says:

function foo(pt) {
  var setX = pt.setX;

or equivalently

function foo(pt) {
  (true && pt.setX)(44);

Under Crock's proposed rule, this will bring about the effect of

    pointMaker.x = 44;

even though one would have thought foo() had no access path whatsoever
to pointMaker. In other words, a lexical-this-defaulting rule as Crock
proposed, and as I gather you seem to be proposing, would cause the
'this' in setX to be bound to the lexically enclosing 'this' when setX
is called as a function. This violates it's authors intent in the same
way that the non-strict global-this-capture does. The only difference
is that inappropriate access is being provided to pointMaker rather
than the global object.

If a lexical this-capture rule can be made to work without these kinds
of problems, it would indeed be better than having to explain
".bind(this)" to ES programmers. Suggestions?


More information about the Es-discuss mailing list