You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

86 lines
2.1 KiB

/*===
args: 1 2 3 4
this: [object global]
args: f2 1 2 3
this: this-f2
args: f2 f3 1 2
this: this-f2
===*/
function orig(x,y,z,w) {
print('args:', x, y, z, w);
print('this:', this);
}
var f1, f2, f3, f4;
f1 = orig;
f2 = f1.bind('this-f2', 'f2');
f3 = f2.bind('this-f3', 'f3');
/* Plain function call, 'this' binding will be the global object. */
f1(1, 2, 3, 4);
/* Bound function: bind 'this' to 'this-f2' and prepend 'f1' to argument list:
*
* f2(1, 2, 3)
* --> f1('f2', 1, 2, 3) this='this-f2'
*/
f2(1, 2, 3);
/* Second order bound function: note the behavior of the this binding:
*
* f3(1, 2)
* --> f2('f3', 1, 2) this='this-f3'
* --> f1('f2', 'f3', 1, 2) this='this-f2'
*
* In other words:
*
* - The effective 'this' binding comes from the bound function right before
* the actual non-bound function (not the outermost bound function).
*
* - The argument list to be prepended (for the final non-bound function call)
* can be formed by concatenating the [[BoundArgs]] lists of the bound
* functions, from innermost to outermost. Or alternatively, by starting
* with an empty list, process each bound function from outermost to innermost,
* prepending the [[BoundArgs]].
*/
f3(1, 2);
/*===
args: 1 2 3 4
this: this-f2
args: 1 2 3 4
this: this-f2
===*/
/* Example of [[BoundArgs]] concatenation:
*
* f1 <-- f2, [[BoundArgs]] = [1,2] <-- f3, [[BoundArgs]] = [3,4]
*
* Process from outermost to innermost, prepending [[BoundArgs]]
*
* []
* [3,4] + [] = [3,4] (process f3)
* [1,2] + [3,4] = [1,2,3,4] (process f2)
* [1,2,3,4] (f1 is not bound, finish)
*
* The ultimately effective [[BoundThis]] is the one right before the non-bound
* function, i.e. f2's [[BoundThis]] here.
*
* For a "collapsed" bound function:
*
* [[BoundArgs]] = [1,2,3,4]
* [[BoundThis]] = 'this-f2'
* [[TargetFunction]] = f1
*/
f1 = orig;
f2 = f1.bind('this-f2', 1, 2);
f3 = f2.bind('this-f3', 3, 4);
f4 = f1.bind('this-f2', 1, 2, 3, 4); // equivalent to f3
f3();
f4();