2010-10-11 10 views
27

No es la configuración para una broma, realmente estoy preguntando.¿Cómo es que una cadena de Javascript no es un objeto?

Douglas Crockford is fond of saying que en el lenguaje javascript prototypal orientado a objetos no hay necesidad de new.

Explica que new se añadió simplemente para dar a las personas que vienen de (es decir, "clásicos") orientados a objetos lenguajes de programación basados ​​en clases cierto nivel de comodidad:

JavaScript, We Hardly new Ya

JavaScript es una lenguaje prototípico, pero tiene un operador new que intenta hacer que se vea como un lenguaje clásico. Eso tiende a confundir a los programadores, lo que lleva a algunos patrones de programación problemáticos.

Nunca necesita utilizar new Object() en JavaScript. Use el objeto literal {} en su lugar.

Bueno, está bien:

  • new mal
  • {} buena

Pero entonces comentarista Vítor De Araújo pointed out that the two are not the same. Se da un ejemplo que muestra que una string no es como un object:

Un objeto de cadena y un valor de cadena no son la misma cosa:

js> p = "Foo" 
Foo 
js> p.weight = 42 
42 
js> p.weight // Returns undefined 

js> q = new String("Foo") 
Foo 
js> q.weight = 42 
42 
js> q.weight 
42 

El valor de cadena no pueden tener propiedades nuevas. Lo mismo es válido para otros tipos.

¿Qué está pasando aquí que un string no es un object? ¿Estoy confundiendo javascript con algunos otros idiomas, donde todo es un objeto?

+0

... y no estoy de acuerdo totalmente con Crockford: no es es necesario usar 'new Object' (ninguno es' new Array', use '[]' en su lugar), pero si quiere definir una nueva instancia de una clase (pre) definida, realmente debería usar el operador 'new', como en 'new Date()' o 'new SchrodingersCat()'. –

+0

@Marcel Korpel: * "debería usar" *, o ** debe ** * usar *? ¿Hay alguna otra forma de construir un nuevo objeto a partir del prototipo de objeto 'Date'? –

+0

Buena pregunta, en caso de 'Fecha': ** debe **. Si llama a 'Fecha' como una función simple, devuelve la fecha y la hora actuales como una cadena. También vea [Usando el constructor sin operador 'nuevo'] (http://stackoverflow.com/questions/1928342/using-constructor-without-operator-new) y [¿El nuevo operador de Javascript hace algo más que dificultar la vida?] (Http : //stackoverflow.com/questions/1744426/does-javascripts-new-operator-do-anything-but-make-life-difficult) –

Respuesta

57

"Todo es un objeto" ... ese es uno de los grandes errores que existen en todo el idioma.

No todo es un objeto, hay lo que llamamos valores primitivos, que son de cadena, número, booleano, nula, e indefinido.

Es cierto, una cadena es valor primitivo, pero puede acceder a todos los métodos heredados de String.prototype como si se tratara de un objeto.

La propiedad accessor operators (el punto y la notación de corchetes), convierten temporalmente el valor de cadena a un objeto String, para poder acceder a esos métodos, p.:

"ab".charAt(1); // "b" 

Lo que sucede detrás de las escenas es algo como esto:

new String("ab").charAt(1); // "b", temporal conversion ToObject 

Al igual que con los otros valores primitivos, como Boolean, y Number, hay envoltorios de objetos, que son simplemente objetos que contiene el valor primitivo, como en su ejemplo:

var strObj = new String(""); 
strObj.prop = "foo"; 

typeof strObj; // "object" 
typeof strObj.prop; // "string" 

Mientras con un primit ive:

var strValue = ""; 
strValue.prop = "foo"; 

typeof strValue; // "string" 
typeof strValue.prop; // "undefined" 

Y esto sucede porque, de nuevo, el acceso a la propiedad en la segunda línea anterior, se crea un nuevo objeto temporal, como:

var strValue = ""; 
new String(strValue).prop = "foo"; // a new object which is discarded 
//... 
+1

Prefiero no usar mayúsculas con primitivas, como 'boolean' y' number', para evitar confusión con las envolturas de objetos 'Boolean' y' Number' (pero la especificación ECMAScript no lo hace). Además, 'NaN' también es un valor primitivo. –

+0

Marcel, sí, los envoltorios de objetos pueden causar confusión, p. 'if (new Boolean (false)) {alert (': D');}'. Sí, 'NaN', positivo y negativo' Infinity' son valores de [Number type] (http://ecma262-5.com/ELS5_HTML.htm#Section_8.5). – CMS

+1

Ah, sí, 'Infinity', ya pensé que olvidé otro valor. ¿Cómo puede uno olvidar "Infinito"? –

Cuestiones relacionadas