One important thing to note is that JavaScript does not have traditional classes. It's best to forget about "JavaScript classes" and focus on understanding JavaScript's object-oriented programming (OOP) approach, which involves constructor functions like your Model
.
You can access the myEvent
property from any code that has a reference to an object created by new Model
. This includes code within your constructor function (using this
) and any functions called with this
pointing to that object. Alternatively, you can access it externally using someObjReference.myEvent
.
In JavaScript, the value of this
is determined solely by how a function is called, not where it is defined as in some other languages. This difference is discussed further in my blog posts "Mythical methods" and "You must remember this
".
Here's a common pattern for setting up constructor functions with shared methods:
function Foo() {
this.myEvent = new CustomEvent("my event");
}
Foo.prototype.bar = function() {
this.myEvent.fire();
};
// Usage:
var f = new Foo();
f.bar(); // Fires the event indirectly via `bar`
f.myEvent.fire(); // Fires it directly
Note that calling bar
with a different context will result in this
not pointing to an instance of Model
, leading to errors.
Unlike class-based languages like Java or C#, JavaScript functions are not bound to specific objects. Understanding this flexibility and closures in JavaScript is key to effective coding in the language.
To correctly set the value of this
when calling a function, there are two main techniques:
Invoke the function directly from an object property in the same expression:
var f = new Foo();
f.bar(); // <== The key bit
f["bar"](); // <== Also works
By doing this, JavaScript automatically sets this
to the object referenced by f
during the function call. However, splitting the property retrieval and function invocation will prevent this behavior.
Utilize the call
and apply
methods of JavaScript function objects to explicitly set the value of this
:
var f = new Foo();
f.bar(1, 2): // <== Calls `bar` with `this` === `f` and passing in
// the arguments 1 and 2
var b = f.bar;
b.call(f, 1, 2); // <== Does the same thing as f.bar(1, 2)
var args = [1, 2];
b.apply(f, args); // <== Does the same thing as f.bar(1, 2)
Using call
and apply
allows explicit control over setting the value of this
when invoking a function.