开发者

Why is there no implicit this in JavaScript

In JavaScript, this must always be stated explici开发者_开发百科tly when accessing its properties. For example:

function Frobber(x) {
    this.x = x;
    return this;
}

Frobber.prototype.frob = function () {
    // wrong:
    return x * x;
    // right:
    return this.x * this.x;
}

I'm aware I can use with(this) (which is deprecated and generally frowned upon), but why aren't properties of this in scope automatically? I'm thinking there must be a reason for this design decision.


It's similar in Python. The reason is quite simple: You cannot add this, because it clashes with the default scoping rule of searching for non-local variables in the outer scopes. It's possible in statically-typed languages, because the members of the this are known at compile-time.

And what if the made it a dynamic decision, such as "x refers to this.x if this.x !== undefined and otherwise to the variable x" (or any other rule for this that is decided at runtime)? That's very dangerous, as it can shadow local variables based on what this happens to be, i.e. breaking perfectly valid code only for certain objects. Another issue: Should undeclaredVar = ... add a new instance attribute? If not, that would be an ugly asymmetry between implicit and explicit this. If it does create an instance attribute, you'd lose the ability to set global and closure variable from inside functions - not too much of a loss, many would say; but the JS designers seem to have thought otherwise, as they chose global scope as default.

Making "casual variables" shadow instance attributes would be less dangerous, but with deeply nested scopes filled with lots of names, you'd propably end up being forced to use this. in most cases - so less of a net win. For this, and/or propably for other reasons, the designers deemed a shortcut infeasible.


You have to explicitly specify "this" because "window" is implicit instead

Code

function SomeFunc(x) {
    y = x;
    return this;
}

Is the same as

function SomeFunc(x) {
    window.y = x;
    return this;
}


What "this" refers to in Javascript is wholly a function of how the current function has been called.

If it is called as a method (i.e. with the . operator) then 'this' will be set to the object before the dot.

If it is called as a simple function, then 'this' will be the global object (usually the window).

IIRC if you use Function.call, you can set it explicitly.

Javascript is an OO language but does not have classes, and does not (strictly) have methods.


Each function object introduces a new namespace and populates it with its parameters, variables and inner function declarations. If all the properties of the this object were to be injected into this same namespace, the names would collide.

To prevent this collision, you would have to explicitly make sure that each parameter name, local variable name or function declaration name is not the same as any of the properties of the object that is referenced by this.

Since you can dynamically add new properties to an object, you would also have to make sure that any new property that you add, does not collide with all those parameters, variables,... in each of the objects methods.

This would be nearly impossible to deal with.


If x is implied to be this.x, how would you access variables defined as the name x?

function Frobber(x) { this.x = x; }
Frobber.prototype.frob = function() {
   var x = 'WHAT ABOUT ME';
   return x;
}


From JavaScript: The Good Parts (Functions -- Invocation):

There are four patterns of invocation in JavaScript: the method invocation pattern, the function invocation pattern, the constructor invocation pattern, and the apply invocation pattern.

Basically, each of these "patterns" determine how the this reference is defined. If a function is defined as a method of an object, this will refer to the parent object. If the function is not a property of an object, this refers to the global object. If the function is invoked with the new keyword (i.e. as a constructor) then this refers to the newly created object. And finally, if you use the function's apply() method the reference of this is bound to whatever object you specify.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜