View Full Version : reflecting on functions and methods

rnd me
Mar 5th, 2013, 11:26 PM
how can i tell by looking at a function variable if the function acts as a method or as a function?

for example:

var a,b;
a="".bold; b=escape;
} else {
a=ecsape; b="".bold;
a("hello world")


var a,b;
a="".bold; b=escape;
} else {
a=ecsape; b="".bold;
a.call("hello world")

each one of these should fail about half the time.

i want to switch between the last expressions as needed based on some conditional expression, one i can't figure out how to code...

either invocation is fine, and i don't mind always using call() and passing what needs to be there for this and arg[0], but i need to know ahead of time: which one i can use that won't throw when the function body only says [Native Code].

Mar 6th, 2013, 02:11 AM
In JavaScript all functions are methods and all methods are objects. When you use call() the first parameter should be the object you are borrowing from.

Each of those two versions will fail 50% of the time because "ecsape" is undefined and not a function/method and so whe "a" is set to that trying to run a() or a.call() will fail.

Old Pedant
Mar 6th, 2013, 02:41 AM
Ummm...but except for your misspelling of "ecsape", they do *NOT* fail.

Instead, they just produce "undefined". It would be easy if they did fail, of course.

But undefined can work for us, can't it?

How about this somewhat hacky code for starters:

<script type="text/javascript">
var a,b,s;
if ( Math.random() < 0.5 )
a="zamboni".bold; b=escape;
} else {
b="zamboni".bold; a=escape;

s = a("hello world");
if ( (/undefined|object/i).test(s) ) {
document.write( "a doesn't work");
} else {
document.write( s );
s = b("hello world");
if ( (/undefined|object/i).test(s) ) {
document.write( "b doesn't work");
} else {
document.write( s );

The |object is there for, what else, MSIE. A true hack.

Mar 6th, 2013, 04:37 AM
//This example chooses the expression it returns:

//Edited- it is simpler to use strings:

var a= Math.round(Math.random())? 'toUpperCase':'escape',
c= "hello world";

if(c[a]) alert(c[a]());
else if(window[a]) alert(window[a](c));
else alert(a);


with some more work you can account for input
that can be functions or nested Object property names

String.prototype.reval= function(O){
var N, s= String(this);
O= O || window;
N= s.split('.');
while(O && N.length) O= O[N.shift()];
return O || s;

Function.prototype.named= function(){
var i= 0, Rx= /function\s+([^(\s]+)\s*\(/,
tem= this.toString().match(Rx) || '';
if(tem) tem= tem[1];
return tem || '';

var a= Math.round(Math.random())? ''.toUpperCase:escape,
c= "hello world";

var as= a.named? a.named():a;
a=a.reval? a.reval(): a;

if(c[as]) alert(c[as]());
else if(typeof a=='function') alert(a(c));
else alert(as);

Old Pedant
Mar 6th, 2013, 06:58 AM
Well, I did say mine was a hack. <grin/>

Nice, MrHoo. And nicely efficient, too.

rnd me
Mar 6th, 2013, 05:36 PM
hey guy, thanks for posting, i appreciate it a lot. There's some good feedback here.

Let me explain further.

I'm trying to make a Function.prototype method that is closely related to .bind(), but with one upgrade of knowing whether or not the function need "de-methodized", for lack of a better term. That is to say that much like using Function.call, the function prototype should return a new function that expects "this" as it's first argument, but only if needed.

whereas a "free floater" function can be called, a method (ideally generic) needs to have "this" set at call-time.

for example, this works fine:

[1,2,3].map(Math.floor) // ===[1,2,3]

but this does not:

[1,2,3].map("".bold) // ===["<b>undefined</b>", "<b>undefined</b>", "<b>undefined</b>"]

but this 'problem' can easily be fixed using bind:

[1,2,3].map( Function.call.bind("".bold) ) // ===["<b>1</b>", "<b>2</b>", "<b>3</b>"]

so, i want a prototype method that keeps me from having to type out the call wrapper for methods.

that part i can handle, no problem:

{get:function(){ return Function.call.bind(this); }}

which means i can now do this:

[1,2,3].map("".bold.free) // === ["<b>1</b>", "<b>2</b>", "<b>3</b>"]

now, i'm spoiled and i want to be able to call ANY function with this prototype, not just methods. I would also like to be able to apply several functions in some automated manner, and NOT have to manually set each one to use ".free" or not. It;s asking a lot, i know.

The proposed solutions require global objct membership, which i can't guarntee. This means that they won't work for me. I also don't want to rely on naming conventions or strict prototype method membership because of generics like
(function(){return [].sort.call(arguments);}) (3,1,2)
[].map.call("12345", Number ).

Consider that the function might not be global, and that this prototype should run without the window Object in places like node.js.

One final restriction: ideally, the function in question should not have to be pre-executed. while that's fine for "".bold, if the function was dbTables.dropAll(), i wouldn't want it firing without me telling it to. ;)

To be fair, i'm not sure this can even be done.

I am hoping there is some way of inferring the this binding using inspection instead of execution.

rnd me
Mar 7th, 2013, 06:49 PM
im guessing from the lack of subsequent responses that what i'm asking cannot be done.

this is mainly for using built-in methods. i think PM might be on to something with his scanning. I wonder if a whitelist could be fashioned to instruct the prototype method on what are native methods. Still, i'd hate to have to maintain such a list...

rnd me
Mar 8th, 2013, 02:43 AM
ok, so i figured out a way to do this.
it just takes iterating the available primitive prototype methods of native types, and flagging them as needing this/call.

what good is all this?

it let's you do quite a bit of data and string manipulation on complete sets of values instead of one-at-a-time.
Normally, it takes quite a few hand-written function to really use [].map/[].filter in a project. Some of these are core logic, but many are tiny wrapper around native code.

With argument homogenization, these built-in methods can run side-by-side with normal functions.

knowing that, we can now stack them in pre-arranged ways ( .before/.after ).

with a few functional programming helper methods on every function, we get enough fine-grain control over flow and execution that the paradigm starts to become usable.

this is just a demo, but hopefully it shows the potential for these types:

(function useBuilder(primitives){

//this bad-boy powers all the others:
if (!Function.use) {
Function.prototype, "use", {
get: function _get() {
return this[" gotta use call "]===null ? Function.call.bind(this) : this.bind(self);
} /* end _get() */
} /* end if(!Function.use) */

//this is the good one:
Function.prototype.after = function(fn) {
var me = this,
early = [].slice.call(arguments, 1);
return function(aa) {
var args = [].slice.call(arguments);
return me.use.apply(this, [fn.use.apply(this, [aa].concat(early))].concat(args.slice(1)))

var me = this,
early = [].slice.call(arguments, 1);
return function(aa) {
var args = [].slice.call(arguments);
return fn.use.apply(this, [me.use.apply(this, [aa].concat(args).slice(1))].concat(early))

/* next 3 are just used for functional programming HTML table builder:
Function.prototype.rebind=function(arg1, arg2){
var that=this.use;
return function(a,b,c){ return that.use(a,arg1,arg2!==undefined?arg2:b) }
var that=this.use;
return function(a,b,c){ return that.use.call(this, a)||fn.call(this,a) || a; }
var that=this.use;
return function(a,b,c){ if(b){that=fn.use;} return that.call(this,a); }

//flag all native this-needing primitive prototype methods with a low-collision hidden property:
primitives.map(function(primitive) {
var mom = primitive.constructor.prototype;
return Object.getOwnPropertyNames(mom).map(function(methodName) {
var functionObject = primitive[methodName];
if (
["valueOf", "toString", "constructor"].indexOf(methodName) === -1 &&
functionObject && functionObject.call &&
!functionObject.hasOwnProperty(" gotta use call ")
Object.defineProperty(functionObject , " gotta use call ", {
value: null
} /* end if usable method */
return methodName;
});//next proto
});//next primitive

//flag the prototype methods of these instances as needing a special "this" context:
}( [ "", 1, /./, false, new Date, [] ] ));

how about an example?
sure, here's a demo step-up:

[1].map( "".bold.use ); // ["<b>1</b>"]
[1].map( btoa ); // ["MQ=="]
[1].map( btoa.use ); // ["MQ=="]
[1].map( "".bold.after(btoa) ); // ["<b>MQ==</b>"]
[1].map( btoa.before("".link, "#sample") ) // ["<a href=\"#sample\">MQ==</a>"]

when you combine them, things get interesting quickly:

.before("".link, "#sample")

which outputs:

["<a href=\"#sample\"><BIG>A</BIG></a>"]

you can change the order of execution by swapping before and after, or by flipping the logic itself.

this isn't the simplest way to make a table from a csv, but it works and shows how you can actually get something done without using a single variable or return statement to perform the task:

csv to HTML table in 1 expression and no returns:


"".split.rebind(/,/, 999 )
[].map.rebind( String.or(Number) )
[].map.rebind( "".big.rebind(null) )
.replace(/big>/g,"td> ")
.replace(/tt>/g,"tr> ")
.replace(/<b>/g,"<table><thead>\n<tr> ")
.replace(/<\/b>/g,"</tr></thead><tbody> ")
.replace(/<\/tr>\s*$/,"</tr></tbody></table> ")

note all the jank at the bottom. you can see how it's better at processing lists than formatting them.

i've already started using this before/after pattern on my SQL interpreter for Arrays of Objects, and it's been the missing piece that can add minor forks to my existing logic with little repetition.