@@ -91,6 +91,22 @@ if (!isNodeJs) {
91
91
92
92
//Gets a member on a role player - can be either a role method or a method or property of the role player object
93
93
export function getRoleMember ( context : Object , player : Object , roleName : string , memberName : string ) {
94
+ if ( player != context [ roleName ] ) {
95
+ //If we're here, it's because the programmer used `this` inside a closure inside a role method.
96
+ //So either `this` refers to some other object besides the current role, or the programmer used `this`
97
+ //inside a closure when they should have used `self`.
98
+ //
99
+ //In other words this code would also be reached if `this` is equal to `undefined`, `global`, or `window`.)
100
+ //...for example, if the SourceAccount.transferOut() method in the Transfer Money example contained the following code:
101
+ // [1,2,3].forEach(function() {
102
+ // this.withdraw(); //`this` is actually equal to `window` or `global` here! (or `undefined` in strict mode)
103
+ // });
104
+ //
105
+ //Because we need to account for the first case (`this` refers to some other object besides the current role),
106
+ //which is perfectly valid, we simply return the property on `this` just as would happen normally in Javascript.
107
+ return player [ memberName ] ;
108
+ }
109
+
94
110
var roleMethod = context [ '__$' + roleName ] [ memberName ] ;
95
111
if ( roleMethod ) {
96
112
//bind the role player as `this` on the specified role method
@@ -105,8 +121,6 @@ export function getRoleMember(context: Object, player: Object, roleName: string,
105
121
}
106
122
}
107
123
108
-
109
-
110
124
//This function is for handling calls beginning with `this`; it calls a method on the current role player,
111
125
//which could be either a role method or a method on the data object.
112
126
//
0 commit comments