Reputation: 2840
I've got a "class" that looks like this:
export function IBXMReplay() {
var onRow = function(){console.log("not right")};
....
}
Later on, it's called in a function like this:
var seqRow = function() {
onRow();
....
}
This function is essentially called by callbacks for web audio getAudio. I construct the object like this:
var replay = new IBXMReplay();
replay.onRow = function(){console.log("Right")};
However, when onRow() is called, it always prints "not right."
What am I doing wrong??? I tried creating a setter function but that didn't work either.
Upvotes: 0
Views: 38
Reputation: 911
The problem is that the onRow
function is being defined as a variable in the IBXMReplay
local scope, and i'm assuming that the seqRow
function is also inside IBXMReplay
. Local-scope variables cannot be directly accessed nor modified from the outside.
For this to work, you'd need to make the onRow
function a property of the IBXMReplay
object (in JS functions are objects too):
export function IBXMReplay() {
this.onRow = function(){console.log("not right")};
....
}
Or better yet, store it in the prototype:
var IBXMReplay = function IBXMReplay() {
....
}
IBXMReplay.prototype.onRow = function(){console.log("not right")};
export IBXMReplay
Either way, you can later do:
var replay = new IBXMReplay();
replay.onRow = function(){console.log("Right")};
It should work as you expected.
Now, some explanation about that. Let's say you have 100 instances of the IBXMReplay
'class'. The differences between storing it as an object property vs. a prototype property are subtle but important:
Storing the method like this.onRow
will mean there'll be 100 copies of it in memory. If you later edit it with replay.onRow = something
, it'll be completely replaced for that particular instance.
Doing something like delete replay.onRow
would not bring the original function back and will instead throw an 'undefined is not a function' error when executing that instance..
Storing the function in the object's prototype instead will mean there'll only be a single copy of onRow
being referenced by all instances. When editing the instance with replay.onRow = something
, the underlying prototype onRow
is merely being shadowed by an object property with the same name, so any calls inside the IBXMReplay
class will reference the overriding function instead.
Deleting the instance property delete replay.onRow
will 'uncover' the original function.
This is how JavaScript works, and is called the prototype chain. Whenever you do foo.bar
, a bar
property is searched directly in the foo
object, but if not found then it's searched in foo
's prototype, and then the prototype's prototype, and so on, until reaching null
, which has no prototype.
Upvotes: 1