2011-02-28 8 views
24

¿Qué está pasando aquí? Justo cuando pensaba que conocía a JS por dentro y por fuera, esta gema aparece.un "this" de String.prototype no devuelve una cadena?

String.prototype.doNothing = function() { 
    return this; 
}; 

alert(typeof 'foo'.doNothing()) // object 
alert(typeof 'foo')    // string 

http://jsfiddle.net/dJBmf/

Esta es romper algunas cosas que esperan una cadena, tales como el método de jQuery .text(str).

+0

use 'this.valueOf()' y usted debería estar bien, esto debería funcionar globalmente sin importar en qué modo se encuentre. @ La respuesta de Bob responde el problema porque enaugh :) –

Respuesta

22

Here's a thorough overview de la palabra clave this. Básicamente, JavaScript lo convierte en un objeto, si no fuera uno.

Los siguientes pasos se realizan cuando control entra en el contexto de ejecución para código de función contenido en función objetivo F, una persona que llama proporcionado EsteValor, y una persona que llama proporcionado argumentsList:

  1. Si el el código de función es un código estricto, establezca ThisBinding en thisValue.
  2. Si este valor es nulo o indefinido, establezca ThisBinding en el objeto global .
  3. Else si Tipo (thisValue) no es Object, establezca ThisBinding en ToObject (thisValue).
  4. establece lo contrario el ThisBinding a EsteValor

Lo mismo sucede con los números y booleanos. Una función similar DoNothing devolvería un tipo de objeto.

+0

Cadena graciosa: aunque las cadenas de javascript son en realidad objetos, se consideran tipos básicos, por lo que tienen su propio tipo y no se consideran objetos. Por otro lado, las matrices se consideran objetos ya que son no es un tipo básico –

31

Para asegurarse de que siempre está recibiendo una cadena, tratando de utilizar este código:

String.prototype.doNothing = function() { 
    return this.toString(); 
}; 

alert(typeof 'foo'.doNothing()) 
alert(typeof 'foo') 

En el código original this está siendo devuelto como objeto cadena y no la cadena real.

+8

Eso funciona, gracias. ¿Puedes elaborar o vincular algo que explique este comportamiento? – adamJLev

+2

¿por qué no simplemente devuelve la cadena '.valueOf()'? :) –

0

Trate return String(this); en lugar de return this;

0

Para tener una mejor comprensión de lo que está pasando trate de usar los registros de consola, así:

String.prototype.doNothing = function() { 
    console.log(this); 
    return this; 
}; 

console.log(typeof 'foo'.doNothing()); 
console.log(typeof 'foo'); 

Estos son los resultados que obtengo en Firefox:

foo { 0="f", 1="o", more...} 
object 
string 

Parece que en el prototipo una cadena se representa como un objeto/una matriz de caracteres (lo cual tiene sentido)

Si debe usar toString (como sugiere McHerbie) o casting como tipo String (como lo sugiere mellamokb) depende, en mi opinión, de lo que planea hacer con este valor. Me inclinaría personalmente hacia lanzarlo como una Cadena.

+0

Sí, vi lo de la consola, ya que el tipo es "objeto" firebug utiliza el estilo de salida "inspección de objetos". Así que esto engaña a Firebug también ... – adamJLev

1

Podría haber también utilizaron la propiedad constructor:

'foo'.constructor === String; //=>true 
'foo'.doNothing().constructor === String; //=>true 

Véase también this SO question y esto jsFiddle

Si String.prototype.doNothing() rompe cosas esperando un valor de cadena, me gustaría utilizar return String(this) o this.toString() (this.valueOf() también funciona aquí) de hecho.

5

ejecutar el código en modo de strict para obtener su resultado esperado!

Cuestiones relacionadas