24

Sto scrivendo un po 'di JavaScript che utilizza il metodo Object.bind.Come gestire la mancanza del metodo JavaScript Object.bind() in IE 8

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); 
}; 

Dal momento che sviluppo in WinXP con Firefox e, talvolta, di prova in Win7 con IE 9 o 10, non ho notato o pagare l'attenzione sul fatto che IE8 e al di sotto non supportano bind.

Questo particolare script non utilizza la tela, quindi sono un po 'titubante a cancellare tutti gli utenti di IE 8.

Esiste una soluzione standard?

Sto andando in giro o va bene in JavaScript, ma sono ancora un po 'noob. Quindi perdonami se la soluzione è totalmente ovvia.

+0

@micha, Sì, manca: 'Non supportato nelle seguenti modalità di documenti : Stranezze, standard di Internet Explorer 6, standard di Internet Explorer 7, standard di Internet Explorer 8. – Alexander

risposta

49

C'è una buona sceneggiatura compatibilità in questa pagina: https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

Basta copiare e incollare nel vostro script.

MODIFICA: posizionando lo script di seguito per chiarezza.

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; 
    }; 
} 
+2

Che ha funzionato come un fascino.Ho trovato una soluzione per il problema del bind e ho imparato a cercare la parola chiave Compatibilità nei documenti di Mozilla. – Claude

+0

A proposito, risulta che IE 8 ha troppe funzionalità mancanti. Fondamentalmente, ho bisogno di attaccare con i browser compatibili con HTML5. Senza il pratico dandy Audio() non ha senso. – Claude

+0

@alex - sai se IE10 supporta bind o ha bisogno del work-around che hai menzionato? –

4

La soluzione migliore potrebbe essere quella di installare Modernizr.

Modernizr ti dice se il browser corrente ha questa funzione nativamente implementata o meno e fornisce un caricatore script in modo si può tirare in polyfills per riempire funzionalità in vecchi browser.

Ecco il link per generare la versione personalizzata Modernizr:
http://modernizr.com/download/#-teststyles-testprop-testallprops-hasevent-prefixes-domprefixes

+0

Come verificare se il browser corrente ha questa funzionalità implementata in modo nativo o non utilizzando Modernizer? – dragonfly

+3

Questa risposta è completamente sbagliata e alquanto corretta! È totalmente sbagliato perché Modernizr non offre un test per la disponibilità del binding di funzioni (probabilmente perché il test è semplice come controllare se 'Function.prototype.bind! == undefined'). Tuttavia, è un po 'corretto perché Modernizr include in realtà una funzione di polyfill di binding! Dettagli di inclusione qui: https://github.com/Modernizr/Modernizr/issues/478 – WickyNilliams

+0

Modernizr> 3 ora non include più il polyfill per rilegare – gunnx

0

Il costruttore funzione è il vecchio modo di fare questo:

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));

Riferimenti

2

Function.prototype.bind non è supportata in Internet Explorer 8 e sotto. la tabella di compatibilità qui: http://kangax.github.io/es5-compat-table/

Mozilla Developer Network fornire questa alternativa per i browser meno recenti che non implementate .bind() in modo nativo:

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; 
    }; 
}