2011-06-16 11 views
15

En Mozilla Developer Center, hay una página sobre la función Function.prototype.bind y proporciona una función de compatibilidad para navegadores que no admiten esta función.Motivo detrás del uso de 'instanceof function() {}'?

Sin embargo, al analizar este código de compatibilidad no puedo averiguar por qué usan instanceof nop. nop se ha establecido en function() {}. ¿Con qué parte de la especificación ECMA en bind corresponde esto? ¿Y qué variables son una instancia de function() {}?

Lo siguiente devuelve false, por lo que no sé para qué se utiliza. ¿Qué cosas devuelven la verdad al hacer un cheque instanceof function() {}?

(function() {}) instanceof (function() {}) // false 

El código es el siguiente:

Function.prototype.bind = function(obj) { 
    if(typeof this !== 'function') 
     throw new TypeError('Function.prototype.bind - what is trying to be bound is not callable'); 

    var slice = [].slice, 
     args = slice.call(arguments, 1), 
     self = this, 
     nop = function() {}, 
     bound = function() { 
      return self.apply(this instanceof nop ? this : (obj || {}), 
           args.concat(slice.call(arguments)));  
     }; 

    bound.prototype = this.prototype; 

    return bound; 
}; 

Respuesta

8

Alguien editado por la parte que lo hace útil. Aquí está lo que solía ser:

Function.prototype.bind = function(obj) { 
    var slice = [].slice, 
    args = slice.call(arguments, 1), 
    self = this, 
    nop = function() {}, 
    bound = function() { 
     return self.apply(this instanceof nop ? this : (obj || {}), 
          args.concat(slice.call(arguments)));  
    }; 

    // These lines are the important part 
    nop.prototype = self.prototype; 
    bound.prototype = new nop(); 

    return bound; 
}; 

respondí otra pregunta que pedía lo mismo (pero cuando el código era correcta) aquí: mozilla's bind function question.

El motivo de la comprobación this instanceof nop es por lo que si se llama a la función de cota como constructor (es decir, con el operador new), this está obligado al nuevo objeto en lugar de lo que pasó a bind.

para explicar la "parte importante", nop es básicamente conseguir inserta en la cadena de prototipos de manera que cuando se llama a la función como un constructor, thises una instancia de nop.

Así que si ejecuta var bound = original.bind(someObject); la cadena de prototipo se verá así:

 
    original 
    | 
    nop 
    | 
    bound 

Mi conjetura por qué utilizaron nop en lugar de this instanceof self es para que la función de límite tendría su propio prototype propiedad (que hereda de self). Es posible que se suponga que no, por lo que podría ser parcialmente editado. De todos modos, el código tal como está ahora no es correcto, pero funcionará siempre que no use la función como constructor.

3

Parece que hay un error con la aplicación. nop nunca se utiliza (para crear una instancia de nada) esperar que instanceof comprobar, que nunca puede ser cierto para nada, ya que no se puede instanciar ningún objeto desde nop, que está enterrado en ese cierre.

Considera:

// Identical definition, but different Function instances 
var nop = function() {}, 
    mop = function() {}; 

var obj1 = new mop; 

obj1 instanceof mop // true 
obj1 instanceof nop // false 
Cuestiones relacionadas