In this snippet of Google Closure javascript code involving a constructor, why is goog.base(this);
necessary? Doesn't Foo
already inherit from Disposable with goog.inherits(foo, goog.Disposable);
?
goog.provide('Foo');
/**
* @constructor
* @extends {goog.Disposable}
*/
Foo = function() {
goog.base(this);
}
goog.inherits(foo, goog.Disposable);
foo.prototype.doSomething = function(){
...
}
foo.prototype.disposeInternal = function(){
...
}
In JavaScript,
this
is set entirely by how the function is called, not where it's defined (as it is in Java, C#, and C++). So to makethis
within the call togoog.Disposable
be thethis
of where you're calling it, you have to use.call
or.apply
. Otherwise, if you just calledgoog.Disposable()
, within the callthis
would begoog
.Basically, there are two ways to set
this
for the function you're calling:Use
obj.func()
orobj["func"]()
notation — e.g., make the call as part of the same overall expression where you're retrieving a property from the object. This tells the engine that within the call, you wantthis
to refer toobj
.Use
call
orapply
to be more explicit about it by supplying the object to use asthis
as the first argument. The only difference betweencall
andapply
is how you supply other arguments: Withcall
, you supply them as discrete args, e.g.foo.call(obj, 1, 2, 3)
callsfoo
withthis
set toobj
and the arguments1
,2
, and3
. Withapply
, you supply the arguments as an array-like second argument:foo.apply(obj, [1, 2, 3]);
(note the[
and]
; e.g.var a = [1, 2, 3]; foo.call(obj, a);
More to explore:
this
You can see
As:
goog.inherits(childConstructor, parentConstructor)
goog.inherits()
establishes the prototype chain from the child constructor to the parent constructor.In addition to prototype properties, constructors may have "own" properties (i.e. instance-specific properties added to
this
). Sincegoog.inherits()
does not call the parent constructor, own properties are not copied to the child constructor and any initialization code in the parent does not get executed. For these reasons, the standard pattern is to chain constructors as in the following example.goog.base(self, opt_methodName, var_args)
goog.base()
is a helper function for calling parent methods so that you do not need to explicitly use call() or apply().In Closure code it is common to chain constructors with
goog.base()
rather than calling the parent constructor explicitly.Further Reading
goog.inherits()
- Classical Pattern #5--A Temporary Constructor)