length array javascript string

array - ¿Son inmutables las cadenas de JavaScript? ¿Necesito un "generador de cadenas" en JavaScript?



slice javascript (10)

Con respecto a su pregunta (en su comentario a la respuesta de Ash) sobre el StringBuilder en ASP.NET Ajax, los expertos parecen no estar de acuerdo en esto.

Christian Wenz dice en su libro Programming ASP.NET AJAX (O''Reilly) que "este enfoque no tiene ningún efecto medible en la memoria (de hecho, la implementación parece ser más lenta que el enfoque estándar)".

Por otro lado, Gallo y otros dicen en su libro ASP.NET AJAX en Acción (Manning) que "cuando el número de cadenas a concatenar es mayor, el creador de cadenas se convierte en un objeto esencial para evitar enormes caídas de rendimiento".

Supongo que necesitaría hacer su propia evaluación comparativa y los resultados también podrían diferir entre los distintos navegadores. Sin embargo, incluso si no mejora el rendimiento, podría considerarse "útil" para los programadores que están acostumbrados a codificar con StringBuilders en lenguajes como C # o Java.

¿Javascript usa cadenas inmutables o mutables? ¿Necesito un "generador de cadenas"?


El valor del tipo de cadena es inmutable, pero el objeto String, que se crea mediante el constructor String (), es mutable, porque es un objeto y puede agregarle nuevas propiedades.

> var str = new String("test") undefined > str [String: ''test''] > str.newProp = "some value" ''some value'' > str { [String: ''test''] newProp: ''some value'' }

Mientras tanto, aunque puede agregar nuevas propiedades, no puede cambiar las propiedades ya existentes

Captura de pantalla de una prueba en la consola de Chrome.

En conclusión, 1. todo el valor del tipo de cadena (tipo primitivo) es inmutable. 2. El objeto String es mutable, pero el valor del tipo de cadena (tipo primitivo) que contiene es inmutable.


Es un post tardío, pero no encontré una buena cita de libro entre las respuestas.

Aquí está un definitivo excepto de un libro confiable:

Las cadenas son inmutables en ECMAScript, lo que significa que una vez que se crean, sus valores no pueden cambiar. Para cambiar la cadena mantenida por una variable, la cadena original debe destruirse y la variable debe rellenarse con otra cadena que contenga un nuevo valor ... —Professional JavaScript for Web Developers, 3rd Ed., P.43

Ahora, la respuesta que cita el extracto del libro de Rhino es correcta acerca de la inmutabilidad de la cadena, pero dice erróneamente que "las cadenas se asignan por referencia, no por valor". (Probablemente originalmente querían poner las palabras de manera opuesta).

El concepto erróneo de "referencia / valor" se aclara en el "JavaScript profesional", capítulo denominado "Valores primitivos y de referencia":

Los cinco tipos primitivos ... [son]: Indefinido, Nulo, Booleano, Número y Cadena. Se dice que se accede a estas variables por valor, porque está manipulando el valor real almacenado en la variable. —Professional JavaScript para desarrolladores web, 3ª ed., P.85

eso es opuesto a los objetos :

Cuando manipulas un objeto, realmente estás trabajando en una referencia a ese objeto en lugar del objeto real en sí. Por esta razón, se dice que se accede a dichos valores por referencia. —Professional JavaScript para desarrolladores web, 3ª ed., P.85


Las cadenas de JavaScript son de hecho inmutables.


Las cadenas en Javascript son inmutables.


Solo para aclarar las mentes simples como la mía (de MDN ):

Los inmutables son los objetos cuyo estado no se puede cambiar una vez que se crea el objeto.

Cadena y números son inmutables.

Inmutable significa que:

Puede hacer que un nombre de variable apunte a un nuevo valor, pero el valor anterior todavía se mantiene en la memoria. De ahí la necesidad de recolección de basura.

var immutableString = "Hello";

// En el código anterior, se crea un nuevo objeto con valor de cadena.

immutableString = immutableString + "World";

// Ahora estamos agregando "Mundo" al valor existente.

Esto parece que estamos mutando la cadena ''immutableString'', pero no lo estamos haciendo. En lugar:

Al agregar el "immutableString" con un valor de cadena, ocurren los siguientes eventos:

  1. Se recupera el valor existente de "immutableString"
  2. "Mundo" se añade al valor existente de "immutableString"
  3. El valor resultante se asigna a un nuevo bloque de memoria.
  4. El objeto "immutableString" ahora apunta al espacio de memoria recién creado
  5. El espacio de memoria creado anteriormente ahora está disponible para la recolección de basura.

del libro de rinocerontes :

En JavaScript, las cadenas son objetos inmutables, lo que significa que los caracteres dentro de ellas no pueden cambiarse y que cualquier operación en cadenas crea realmente nuevas cadenas. Las cadenas se asignan por referencia, no por valor. En general, cuando un objeto se asigna por referencia, un cambio realizado en el objeto a través de una referencia será visible a través de todas las demás referencias al objeto. Sin embargo, como las cadenas no se pueden cambiar, puede tener varias referencias a un objeto de cadena y no preocuparse de que el valor de la cadena cambie sin que usted lo sepa.


Consejo de rendimiento:

Si tiene que concatenar cadenas grandes, coloque las partes de la cadena en una matriz y use el método Array.Join() para obtener la cadena general. Esto puede ser muchas veces más rápido para concatenar un gran número de cadenas.

No hay StringBuilder en JavaScript.


Las cuerdas son inmutables , no pueden cambiar, solo podemos hacer nuevas cuerdas.

Ejemplo:

var str= "Immutable value"; // it is immutable var other= statement.slice(2, 10); // new string


Son inmutables. No puede cambiar un carácter dentro de una cadena con algo como var myString = "abbdef"; myString[2] = ''c'' var myString = "abbdef"; myString[2] = ''c'' . Los métodos de manipulación de cadenas, como el trim y el trim , devuelven nuevas cadenas.

Sin embargo, siempre he escuchado lo que Ash mencionó en su respuesta (que usar Array.join es más rápido para la concatenación), así que quise probar los diferentes métodos de concatenar cadenas y extraer la forma más rápida en un StringBuilder. Escribí algunas pruebas para ver si esto es cierto (¡no lo es!).

Esto era lo que creía que sería la forma más rápida, aunque seguía pensando que agregar una llamada a un método puede hacerlo más lento ...

function StringBuilder() { this._array = []; this._index = 0; } StringBuilder.prototype.append = function (str) { this._array[this._index] = str; this._index++; } StringBuilder.prototype.toString = function () { return this._array.join(''''); }

Aquí están las pruebas de velocidad de rendimiento. Los tres crean una cadena gigantesca formada por concatenar "Hello diggity dog" cien mil veces en una cadena vacía.

He creado tres tipos de pruebas.

  • Usando Array.push y Array.join
  • Usando la indexación de Array para evitar Array.push , y luego usando Array.join
  • Concatenación de cuerdas rectas

Luego creé las mismas tres pruebas al abstraerlas en StringBuilderConcat , StringBuilderArrayPush y StringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5 Por favor, vaya allí y haga pruebas para que podamos obtener una buena muestra. Tenga en cuenta que corregí un pequeño error, por lo que los datos de las pruebas se borraron, actualizaré la tabla una vez que haya suficientes datos de rendimiento. Vaya a http://jsperf.com/string-concat-without-sringbuilder/5 para obtener la tabla de datos anterior.

Aquí hay algunos números del 21 de febrero de 2013, si no desea seguir el enlace. El número en cada prueba está en operaciones / segundo (cuanto más alto, mejor )

| Browser | Index | Push | Concat | SBIndex | SBPush | SBConcat | --------------------------------------------------------------------------- | Chrome 24.0.1312 | 83 | 87 | 702 | 69 | 87 | 165 | | Chrome 25.0.1364 | 43 | 47 | 620 | 42 | 42 | 68 | | Firefox 10.0.10 | 164 | 164 | 533 | 164 | 16 | 421 | | Firefox 19.0 | 70 | 70 | 259 | 70 | 70 | 186 | | Exploder 7.0 | 51 | 33 | 58 | 31 | 37 | 45 | | Exploder 8.0 | 48 | 30 | 58 | 30 | 36 | 36 | | Exploder 9.0 | 87 | 64 | 95 | 61 | 61 | 61 | | Opera 12.14 | 125 | 154 | 66 | 106 | 137 | 63 |

Recomendaciones

  • Hoy en día, todos los navegadores manejan bien la concatenación de cadenas. Array.join solo ayuda a Opera

  • En general, Chrome es el más rápido, registrando 1025 ops / seg en 27.0. 10 veces más rápido que usar Array.join ()

  • Firefox se encuentra en el segundo lugar con alrededor de 550 ops / seg (pero 20.0 parece haber retrocedido). Array.join es aproximadamente 4-5 veces más lento.

  • IE es más rápido con la concatenación de cuerdas rectas, es muy lento con Array.join y Array.push . IE 9 hace que Array.join no sea tan lento, y todas las abstracciones de la SB funcionan casi de la misma manera (probablemente debido a la sobrecarga del método)

  • Opera es el único en el que Array.join realmente ayuda, es 2-3 veces más rápido que la concatenación de cuerdas.

  • Crear un StringBuilder para abstraer los problemas de rendimiento de cada navegador hace más daño que bien. La sobrecarga de las llamadas a métodos puede ser aceptable, pero la tendencia parece ser que los navegadores manejan la concatenación de cadenas de manera más inteligente. Solo tendría sentido si su público objetivo es Opera, por lo que puede usar Array. Únase allí y use la concatenación de cadenas en cualquier otro lugar (esto significa que todos los demás navegadores están teniendo un impacto)

Espero que alguien más encuentre esto útil

Caso de prueba diferente

Como @RoyTinker pensó que mi prueba tenía fallas, creé un nuevo caso que no crea una cadena grande al concatenar la misma cadena, usa un carácter diferente para cada iteración. La concatenación de cuerdas todavía parecía más rápida o igual de rápida. Vamos a poner en marcha esas pruebas.

Sugiero que todos deberían seguir pensando en otras formas de probar esto, gracias por la entrada Roy.

http://jsperf.com/string-concat-without-sringbuilder/7