Skip to content

Commit

Permalink
make this respect a target if one is used
Browse files Browse the repository at this point in the history
Otherwise when invoked "globally", `this` is set to the
function instance
  • Loading branch information
TooTallNate committed Jan 1, 2016
1 parent 47906b7 commit 501bbf1
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 3 deletions.
11 changes: 9 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -99,16 +99,23 @@ var fn = createFunction('name', 0, FunctionSubclass, args);
### invoke → Symbol

You use the `invoke` Symbol to define the function to execute when a created
function instance is invoked. Note that `this` in the invoke function is bound to
the created function instance.
function instance is invoked.

Note that `this` in the invoke function is bound to the created function instance
when invoked without a receiver (i.e. "globally"). Otherwise, `this` respects the
left-hand receiver, or target when used with `.call()`/`.apply()`.

``` js
var invoke = require('function-class/invoke');

fn[invoke] = function () {
console.log('fn has been invoked!');
return this;
};

fn();
// fn has been invoked!

assert.equal(fn(), fn);
assert.equal(fn.call(global), global);
```
7 changes: 6 additions & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@ function createFunctionInstance (name, length, constructor, args) {

// create function instance
fn = functionNameArity(name, length, function () {
return fn[invoke].apply(fn, arguments);
"use strict";
var invokeFn = fn[invoke];
if (typeof invokeFn !== 'function')
throw new Error('you must define the `[function-class/invoke]` function on this instance');
var thisArg = typeof this === 'undefined' ? fn : this;
return invokeFn.apply(thisArg, arguments);
});

if (constructor) {
Expand Down
12 changes: 12 additions & 0 deletions test.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,3 +86,15 @@ assert.ok(oneOffCalled);
var snowman = createFunction('⌛', 30);
assert.equal(snowman.name, '⌛');
assert.equal(snowman.length, 30);


// `this` arg
var thisArg = createFunction();
thisArg[invoke] = function () {
return this;
};
assert.equal(thisArg(), thisArg);
assert.equal(thisArg()()(), thisArg());
assert.equal(thisArg.call(global), global);
assert.equal(thisArg.call(1).valueOf(), 1);
assert.equal(thisArg.call(true).valueOf(), true);

0 comments on commit 501bbf1

Please sign in to comment.