-
-
Save atk/1039813 to your computer and use it in GitHub Desktop.
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 <[email protected]> | |
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> |
I don't know the exact definition of "polyfill". How would you call it, then?
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.
I'm still trying to golf a full replacement to 140bytes, but no luck so far...
I need to think out of the box. 140bytes without Function.prototype.bind=(function(){}).bind||
are much more than I need now...
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.
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!
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.
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.
perhaps binding for constructors is too ambitious given the space constraints. i'm okay with that tradeoff.
I'd like to have a full ES5-compatible replacement, even if not as polyfill.
I just wonder why use (function(){}).bind instead of alert.bind or even Function.bind...
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.
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)
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.
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.
suggest one.
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.
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?"))
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.
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.
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
.
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.
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
Then go forth and program responsibly and pray no more, sonnyboy.
I think it's possible to program responsibly and have fun ;D
Where is the damn "Like" button?
@rwldrn: on Facebook. We don't do this worshipping stuff here.
alas, i don't think you can call this a polyfill if it doesn't meet the original API.