Skip to content

Instantly share code, notes, and snippets.

@atk
Forked from 140bytes/LICENSE.txt
Created June 22, 2011 10:11
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save atk/1039813 to your computer and use it in GitHub Desktop.
Function.prototype.bind replacement (not fully functional yet)
Function.prototype.bind = (function(){}).bind ||
function(
a, // new context (new this)
b // placeholder for function (old this)
){
// store function
b = this;
// return new function
return function(){
// calling old function in new scope
b.apply(a,arguments)
}
}
Function.prototype.bind=(function(){}).bind||function(a,b){b=this;return function(){b.apply(a,arguments)}}
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2011 Alex Kloss <alexthkloss@web.de>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
{
"name": "funcbind",
"description": "Function.prototype.bind polyfill, not really ES5-compatible",
"keywords": [
"function",
"prototype",
"bind",
"polyfill"
]
}
<!DOCTYPE html>
<title>Foo</title>
<div>Expected value: <b>works</b></div>
<div>Actual value: <b id="ret"></b></div>
<script>
// write a small example that shows off the API for your example
// and tests it in one fell swoop.
var myFunction = Function.prototype.bind=(function(){}).bind||function(a,b){b=this;return function(){b.apply(a,arguments)}};
(function(){ document.getElementById( "ret" ).innerHTML = this; }).bind('works')();
</script>
@jed
Copy link

jed commented Jun 22, 2011

alas, i don't think you can call this a polyfill if it doesn't meet the original API.

@atk
Copy link
Author

atk commented Jun 22, 2011

I don't know the exact definition of "polyfill". How would you call it, then?

@jed
Copy link

jed commented Jun 22, 2011

it's useful, no doubt about that, but it can't be dropped in for the original. you shouldn't replace Function.prototype.bind with something incompatible, just ask prototype.js.

@atk
Copy link
Author

atk commented Jun 22, 2011

I'm still trying to golf a full replacement to 140bytes, but no luck so far...

@atk
Copy link
Author

atk commented Jul 4, 2011

I need to think out of the box. 140bytes without Function.prototype.bind=(function(){}).bind|| are much more than I need now...

@jed
Copy link

jed commented Jul 4, 2011

yeah, i would be very surprised if this were possible. best for now to get it right over 140, and see where folks take it.

@atk
Copy link
Author

atk commented Jul 4, 2011

Currently, I have 189 bytes (not thoroughly tested yet):

function(a,b,c,d){c=this;d=[].slice.call(arguments,1);b=function(e){e=c.apply((c=this instanceof b)?this:a,e.concat(e.slice.call(arguments)));return c?0:e};b.prototype=c.prototype;return b}

Let the golfing begin!

@jed
Copy link

jed commented Jul 5, 2011

how about

Function.prototype.bind=function(a,b,c){b=[c=this].slice.call(arguments,1);return function(){return a.apply(c,b.concat.apply(b,arguments))}}

as adapted from @WebReflection's example.

@atk
Copy link
Author

atk commented Jul 5, 2011

Will probably fail in the case you try to call bound=function(){}.bind; x=new bound(); - I'll test that later. But the idea of using the Array as delimiter is good. Maybe we should add something about delimiters to the wiki.

@jed
Copy link

jed commented Jul 6, 2011

perhaps binding for constructors is too ambitious given the space constraints. i'm okay with that tradeoff.

@atk
Copy link
Author

atk commented Jul 6, 2011

I'd like to have a full ES5-compatible replacement, even if not as polyfill.

@tsaniel
Copy link

tsaniel commented Jul 6, 2011

I just wonder why use (function(){}).bind instead of alert.bind or even Function.bind...

@atk
Copy link
Author

atk commented Jul 6, 2011

thanks, @tsaniel - this is a good idea; though I am currently trying to omit the polyfill feature in favour of a fully ES5-compatible version that works for constructors, too.

@jdalton
Copy link

jdalton commented Aug 21, 2011

The result of Function#bind should still be able to work as a constructor.

Example:

function Alien(type) {
  this.type = type;
}

var thisArg = {};
var Tribble = Alien.bind(thisArg, 'Polygeminus grex');

// `thisArg` should **not** be used for the `this` binding when called as a constructor
var fuzzball = new Tribble;
console.log(fuzzball.type); // "Polygeminus grex"

Because this isn't as ES5 compliant, as possible*, I don't think it should be placed on the Function.prototype.

Note: It is impossible to support a fully compliant Function#bind because by spec bound functions do not have a .prototype property (which is impossible to avoid) and have a specific computed .length property (which can be a pain to implement)

@atk
Copy link
Author

atk commented Aug 22, 2011

If you use bind only for a limited number of cases, this will suffice and fit into the tight space of 140bytes. I already wrote in the title that it is not fully functional. If I find a way to provide the full functionality, I'll change this.

@jdalton
Copy link

jdalton commented Aug 22, 2011

If you use bind only for a limited number of cases, this will suffice and fit into the tight space of 140bytes.

That's fine but it shouldn't be placed on Function.prototype.bind because other scripts after this may assume that a fully functional native bind exists.
A better place would be make this a utility method on another namespace.

@atk
Copy link
Author

atk commented Aug 22, 2011

suggest one.

@jdalton
Copy link

jdalton commented Aug 22, 2011

suggest one

Something like:

(_b = this._b || {}).bind = function(fn, thisArg) { ... };

would do or anything else really as long as it's off the native prototype.
I don't think ES5 fallbacks are the best choice for code golf in general because things should be really tight and follow spec as these methods are added to native prototypes.

@jed
Copy link

jed commented Aug 22, 2011

no worries, guys, i've got a fix. just make sure to prepend this to any polyfills, okay?

if(!confirm("are you John-David Dalton?"))

@atk
Copy link
Author

atk commented Aug 22, 2011

Now you're being sarcastic, @jed. As for you, @jdalton, remember RFC 1925, 1 - polyfills need not be 100% spec compliant as long as they get the job done.

@jdalton
Copy link

jdalton commented Aug 22, 2011

@jed @atk

remember RFC 1925, 1 - polyfills need not be 100% spec compliant as long as they get the job done.

In this case because browsers have varying support, throwing in consistency issues can cause problems.
MooTools had to change their bind implementation in v1.3 to follow spec because, although their old one got the job done, it was inconsistent enough with the native Function#bind and caused problems between browsers that supported native and those that used their fallback.

@atk
Copy link
Author

atk commented Aug 22, 2011

140bytes snippets are examples of coders ingenuity, many of them not being meant for real-life daily use (unless you know what you're doing). In many cases, either missing standards compliance or performance issues are good reasons to expend more than 140 bytes on a problem. So the point is that you're missing the point.

@jdalton
Copy link

jdalton commented Aug 22, 2011

@atk

So the point is that you're missing the point.

No I get it (as I wrote above, code golf probably isn't the best place for ES5 shims), but I've seen devs promoting file size above all else and using techniques/snippets from code golf in projects which makes me cautious about promoting snippets that enforce bad practices. You can code golf and still do so responsibly by not putting the method on Function.prototype.bind.

@atk
Copy link
Author

atk commented Aug 22, 2011

If one is using snippets from random Gists in your projects, one should either know what one is doing or otherwise be prepared to have the code not working in the expected way. It is not our responsibility what others do with our code. We're here for the fun of coding and we most certainly won't let you spoil it for us, thank you very much.

@jdalton
Copy link

jdalton commented Aug 22, 2011

@atk

We're here for the fun of coding and we most certainly won't let you spoil it for us, thank you very much.

I'm not trying to spoil anything. I think it's possible to program responsibly and have fun ;D

@atk
Copy link
Author

atk commented Aug 22, 2011

Then go forth and program responsibly and pray no more, sonnyboy.

@rwaldron
Copy link

I think it's possible to program responsibly and have fun ;D

Where is the damn "Like" button?

@atk
Copy link
Author

atk commented Aug 24, 2011

@rwldrn: on Facebook. We don't do this worshipping stuff here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment