26

I am writing a bit of JavaScript that uses the Object.bind method.

funcabc = function(x, y, z){ 
    this.myx = x;
    this.playUB = function(w) {
        if ( this.myx === null ) {
            // do blah blah
            return;
        }

        // do other stuff
    };
    this.play = this.playUB.bind(this);
};

Since I develop in WinXP with Firefox and sometimes test in Win7 with IE 9 or 10, I did not notice or pay attention to the fact that IE8 and below do not support bind.

This particular script does not use the canvas, so I'm a little hesitant to write off all IE 8 users.

Is there a standard work-around?

I'm getting around sort of okay in JavaScript, but I'm still a bit of a noob. So forgive me if the solution is totally obvious.

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265
Claude
  • 599
  • 1
  • 5
  • 13
  • @micha, Yes, missing: `Not supported in the following document modes: Quirks, Internet Explorer 6 standards, Internet Explorer 7 standards, Internet Explorer 8 standards.` – Alexander Jun 15 '12 at 16:22

4 Answers4

51

There is a good compatability script on this page: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

Just copy and paste it into your script.

EDIT: placing the script below for clarity.

if (!Function.prototype.bind) {
  Function.prototype.bind = function(oThis) {
    if (typeof this !== 'function') {
      // closest thing possible to the ECMAScript 5
      // internal IsCallable function
      throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable');
    }

    var aArgs   = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP    = function() {},
        fBound  = function() {
          return fToBind.apply(this instanceof fNOP && oThis
                 ? this
                 : oThis,
                 aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
Zanon
  • 29,231
  • 20
  • 113
  • 126
alexwells
  • 1,243
  • 13
  • 16
  • 2
    That worked like a charm. Found a fix for the bind issue and learned to look for the keyword Compatibility in the mozilla docs. – Claude Jun 15 '12 at 16:39
  • By the way, turns out that IE 8 has too many missing features. Basically, I need to stick with HTML5 compatible browsers. Without the handy-dandy Audio() there's no point. – Claude Jun 15 '12 at 16:41
  • @alex - do you know if IE10 supports bind or does it need the work-around you mentioned? –  Jan 15 '13 at 19:57
  • @pure_code - I would assume it does (the bind method has become standard so all new browsers should have it). But I have not tested it and don't have access to IE10 right now. – alexwells Jan 16 '13 at 15:54
  • http://stackoverflow.com/questions/14346781/which-browsers-support-bind....I posted a question on it....good answer with a browser compatibility chart –  Jan 16 '13 at 17:35
  • The article there in the answer is a good short read/skim, if you're sort of fuzzy on the whole `bind` thing. – Ben Apr 03 '14 at 16:11
  • A note that copy and pasting the script from the Mozilla page doesn't work out of the box. Lines 13-14 have a multi-line string which isn't properly terminated with a `\ `. – Matt Jun 22 '14 at 16:28
  • I usually suggest placing polyfills like this into a script tag which is loaded using a conditional comment. That avoids forcing modern browsers to download code they don't need and IE8 is already the slow-lane so one more file is unlikely to make a difference. – Chris Adams Jul 30 '14 at 14:02
4

The best solution could be to install Modernizr.

Modernizr tells you whether the current browser has this feature natively implemented or not and it provides a script loader so you can pull in polyfills to backfill functionality in old browsers.

Here is the link to generate your modernizr custom version:
http://modernizr.com/download/#-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes

antonjs
  • 14,060
  • 14
  • 65
  • 91
  • How to check if the current browser has this feature natively implemented or not using Modernizer? – dragonfly Feb 17 '13 at 16:01
  • 3
    This answer is at once totally wrong and somewhat correct! It's totally wrong because Modernizr does not offer a test for availability of function binding (probably because the test is as simple as inspecting whether `Function.prototype.bind !== undefined`). However, it's somewhat correct because Modernizr actually includes a function bind polyfill itself! Details of it's inclusion here: https://github.com/Modernizr/Modernizr/issues/478 – WickyNilliams Dec 04 '13 at 22:35
  • Modernizr > 3 now no longer includes the polyfill for bind – gunnx Nov 03 '15 at 12:54
2

Function.prototype.bind isn’t supported in Internet Explorer 8 and below. Compatibility chart here: http://kangax.github.io/es5-compat-table/

Mozilla Developer Network provide this alternative for older browsers that don't implemented .bind() natively:

if (!Function.prototype.bind) {
  Function.prototype.bind = function (oThis) {
    if (typeof this !== "function") {
      // closest thing possible to the ECMAScript 5 internal IsCallable function
      throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");
    }

    var aArgs = Array.prototype.slice.call(arguments, 1),
        fToBind = this,
        fNOP = function () {},
        fBound = function () {
          return fToBind.apply(this instanceof fNOP && oThis
                                 ? this
                                 : oThis,
                               aArgs.concat(Array.prototype.slice.call(arguments)));
        };

    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();

    return fBound;
  };
}
Karl Glennon
  • 3,149
  • 4
  • 29
  • 31
0

The Function constructor is the old-fashioned way of doing this:

var foo = function(x,y,z){ return Function("x,y,z","return Math.max.call(this, x, y, z)")(x,y,z) }
 
var bar = function(x,y,z){ return Function("x,y,z","return Math.min.call(this, x, y, z)")(x,y,z) }
 
console.log(foo(1,2,3) );
 
console.log(bar(3,2,1) );

References

Paul Sweatte
  • 24,148
  • 7
  • 127
  • 265