¿Cómo verificar si una cadena "comienza con" otra cadena?

Respuestas:

1773

Puede usar el String.prototype.startsWith()método ECMAScript 6 , pero aún no es compatible con todos los navegadores . Deberá usar una cuña / polyfill para agregarlo en los navegadores que no lo admiten. Crear una implementación que cumpla con todos los detalles establecidos en la especificación es un poco complicado. Si quieres una cuña fiel, usa cualquiera de los siguientes:

Una vez que haya mejorado el método (o si solo admite navegadores y motores de JavaScript que ya lo tienen), puede usarlo así:

"Hello World!".startsWith("He"); // true

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false
CMS
fuente
@gtournie, ¿por qué empezar sería uno de los peores métodos para probar si una cadena comienza con una cadena? (vea su comentario aquí: stackoverflow.com/questions/646628/… ) está más entusiasmado con la comparación de caracteres por carácter. Espero que los compiladores sean lo suficientemente inteligentes como para NO generar una cadena para cada cadena [índice] porque, si simplemente escribes esto: character = string [0], ASIGNARÁ un objeto, infinitamente MENOS eficiente que el uso de beginWith (beginWith no asignará ninguna memoria )
Martijn Scheffer
@MartijnScheffer: La respuesta se ha editado muchas veces desde que respondí y ahora es completamente diferente (eliminé mi comentario;). Estoy de acuerdo en que el método comienza con el ECMAScript 6 es la mejor manera de hacerlo.
gtournie
66
@GrahamLaight, cuando dice que es compatible con 'IE', presumiblemente se refiere a Edge. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Marcus
@ Marcus, disculpas si me equivoqué - mi información vino de: w3schools.com/jsref/jsref_startswith.asp
Graham Laight
¡ADVERTENCIA! Estas pruebas jsperf no funcionan en navegadores que son buenos para compilar JIT. Los navegadores como Firefox y Chrome a veces lo reconocen cuando se descarta el resultado de una operación y, por lo tanto, no realizan la operación . Además de eso, los motores javascript modernos usan predicción de bifurcación , por lo que las cadenas de prueba deben ser diferentes en cada iteración.
Aloso
1283

Otra alternativa con .lastIndexOf:

haystack.lastIndexOf(needle, 0) === 0

Esto mira hacia atrás haystackpara ver si ocurre needledesde el índice 0de haystack. En otras palabras, solo verifica si haystackcomienza con needle.

En principio, esto debería tener ventajas de rendimiento sobre otros enfoques:

  • No busca todo haystack.
  • No crea una nueva cadena temporal y luego la descarta inmediatamente.
Mark Byers
fuente
1
No estoy seguro de qué caso está tomando @ rfcoder89 - jsfiddle.net/jkzjw3w2/1
Gulfaraz Rahman
55
@ rfcoder89 Observe que el segundo parámetro de lastIndexOf: "aba".lastIndexOf ("a")es 2 como señala, pero "aba".lastIndexOf ("a", 0)es 0, lo cual es correcto
maxpolk
1
Muchas gracias. String.startsWith no funciona en Android Lollipop WebView, ¡pero este fragmento lastIndexOf sí funciona!
Herman
con lastIndexOf la cadena se busca desde el final hasta el principio por lo que busca en toda la cadena: por lo que su ineficiencia crece para cadenas muy largas que buscar.
Willy Wonka
8
@willywonka No, no es si tienes 0 startIndex, se busca desde 0 pos y es la única comprobación. Se busca en toda la cadena solo si fromIndex> = str.length.
Greene
588
data.substring(0, input.length) === input
cobbal
fuente
3
@ANeves Sospecho que depende en gran medida del navegador y los datos utilizados. Vea la respuesta de Ben Weaver para medidas reales. En el navegador que estoy ejecutando actualmente (Chrome 12.0.742 en Windows) la subcadena gana por el éxito y la expresión regular preparada gana por el fracaso.
cobbal
44
@cobbal Quizás. Pero .lastIndexOf(input, 0)compara los primeros N caracteres, mientras que .substring(0, input.length) === inputcuenta N, subcadena los datos a N longitud y luego compara esos N caracteres. A menos que haya optimización de código, esta segunda versión no puede ser más rápida que la otra. Sin embargo, no me malinterpretes, nunca encontraría algo mejor de lo que sugeriste. :)
ANeves
2
@ANeves Pero .lastIndexOf en una cadena larga que devolverá falso va a iterar sobre toda la cadena (O (N)), mientras que el caso .substring itera sobre una cadena potencialmente mucho más pequeña. Si espera éxitos mayoritarios o solo pequeñas entradas, es probable que .lastIndexOf sea más rápido; de lo contrario, es probable que .substring sea más rápido. .substring también corre el riesgo de una excepción si la entrada es más larga que la cadena que se verifica.
Chris Moschini
14
@ChrisMoschini, no olvides que la solución de Mark Byers ha lastIndexOfcomenzado en el índice 0, no en el final. Eso también me hizo tropezar, inicialmente. Sin embargo, verificar con qué comienza una cadena es una tarea tan común que JavaScript realmente debería tener una API adecuada para ella, no todas las expresiones idiomáticas y alternativas que ve en esta página, por inteligentes que sean.
Randall Cook el
44
Prefiero la solución de cobbal sobre la de Mark. Incluso si Mark's es más rápido y es un truco impresionante usando los parámetros, es muy difícil de leer en comparación con la subcadena.
ThinkBonobo
184

Sin una función auxiliar, solo usando el .testmétodo regex :

/^He/.test('Hello world')

Para hacer esto con una cadena dinámica en lugar de una codificada (suponiendo que la cadena no contendrá ningún carácter de control regexp):

new RegExp('^' + needle).test(haystack)

Deberías consultar ¿Existe una función RegExp.escape en Javascript? si existe la posibilidad de que los caracteres de control regexp aparezcan en la cadena.

Vincent
fuente
1
Para hacer que la expresión /^he/i
distinga entre
64

Mejor solución:

function startsWith(str, word) {
    return str.lastIndexOf(word, 0) === 0;
}

Y aquí está el final Con si lo necesitas también:

function endsWith(str, word) {
    return str.indexOf(word, str.length - word.length) !== -1;
}

Para aquellos que prefieren crear un prototipo en String:

String.prototype.startsWith || (String.prototype.startsWith = function(word) {
    return this.lastIndexOf(word, 0) === 0;
});

String.prototype.endsWith   || (String.prototype.endsWith = function(word) {
    return this.indexOf(word, this.length - word.length) !== -1;
});

Uso:

"abc".startsWith("ab")
true
"c".ensdWith("c") 
true

Con método:

startsWith("aaa", "a")
true
startsWith("aaa", "ab")
false
startsWith("abc", "abc")
true
startsWith("abc", "c")
false
startsWith("abc", "a")
true
startsWith("abc", "ba")
false
startsWith("abc", "ab")
true
mmm
fuente
Creo que ha mezclado lastIndexOf e indexOf en sus funciones: comienza con debería ser devuelto str.indexOf (word, 0) === 0;
Richard Matheson el
55
@RichardMatheson el problema con el uso de indexOf es que si no coincide al principio, continuará buscando en toda la cadena, por lo que lastIndexOf comienza desde la longitud de la palabra y vuelve a cero. ¿Entendido?
mmm
2
Ah, sí, tiene sentido ahora, no presté atención a los índices que estabas usando. Muy buen truco!
Richard Matheson
54

Solo quería agregar mi opinión sobre esto.

Creo que podemos usar así:

var haystack = 'hello world';
var needle = 'he';

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}
Mr.D
fuente
2
La respuesta de Mark Byers fue comparada por el rendimiento de tres enfoques correctos diferentes por @relfor. Este enfoque correcto no fue favorecido porque requiere buscar en toda la cadena.
maxpolk
@maxpolk Creo indexOfque dejará de buscar una cadena completa cuando encuentre la primera ocurrencia. Lo he comprobado
Mr.D
8
Si la primera aparición no se encuentra al principio, este enfoque comienza a volverse ineficiente cuanto más tiempo continúa buscándolo, posiblemente buscando hasta que llegue al final, en lugar de darse por vencido mucho antes. Debido a que existe un potencial de ineficiencia, no se favorece entre los tres enfoques correctos.
maxpolk
2
@ Mr.D ¿Y si no hay coincidencia?
mmm
más cuando se ha buscado todo el pajar? es mejor: stackoverflow.com/a/36876507/961018 .. solo busca hasta la longitud de la palabra
mmm
39

Aquí hay una pequeña mejora en la solución de CMS:

if(!String.prototype.startsWith){
    String.prototype.startsWith = function (str) {
        return !this.indexOf(str);
    }
}

"Hello World!".startsWith("He"); // true

 var data = "Hello world";
 var input = 'He';
 data.startsWith(input); // true

Comprobar si la función ya existe en caso de que un futuro navegador la implemente en código nativo o si es implementada por otra biblioteca. Por ejemplo, la Biblioteca de prototipos ya implementa esta función.

El uso !es un poco más rápido y más conciso que === 0aunque no tan legible.

Equipo
fuente
1
Esto podría convertirse en un problema: si la implementación ya implementada se comporta de manera diferente a la mía, esto rompería mi aplicación.
Christoph Wurm
2
Esto tiene el problema O (N) discutido aquí stackoverflow.com/questions/646628/javascript-startswith/…
Chris Moschini
1
utilizando ! hay muy desordenado
JonnyRaa
-1; añadiendo que esto String.prototypees una mala idea, ya que no llegan a acercarse al cumplimiento de la especificación para String.prototype.startsWith. Cualquier código que intente usar el método ES6 puede fallar si está haciendo esto; bien puede ver si el método ya está definido, ver si lo está (mal, por usted) y no agregar una cuña que cumpla con las especificaciones, lo que lleva a un comportamiento incorrecto más adelante.
Mark Amery
21

También echa un vistazo a underscore.string.js . Viene con un montón de métodos útiles de prueba y manipulación de cadenas, incluido un startsWithmétodo. De los documentos:

comienza con _.startsWith(string, starts)

Este método verifica si stringcomienza con starts.

_("image.gif").startsWith("image")
=> true
studgeek
fuente
1
Necesitaba_.string.startsWith
Coronel Panic
15

Recientemente me hice la misma pregunta.
Hay varias soluciones posibles, aquí hay 3 válidas:

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(agregado después de ver la respuesta de Mark Byers )
  • usando un bucle:

    function startsWith(s,starter) {
      for (var i = 0,cur_c; i < starter.length; i++) {
        cur_c = starter[i];
        if (s[i] !== starter[i]) {
          return false;
        }
      }
      return true;
    }

No he encontrado la última solución que hace uso de un bucle.
Sorprendentemente, esta solución supera a los primeros 3 por un margen significativo.
Aquí está la prueba jsperf que realicé para llegar a esta conclusión: http://jsperf.com/startswith2/2

Paz

ps: ecmascript 6 (armonía) introduce un startsWithmétodo nativo para cadenas.
Solo piense cuánto tiempo se habría ahorrado si hubieran pensado incluir este método tan necesario en la versión inicial.

Actualizar

Como Steve señaló (el primer comentario sobre esta respuesta), la función personalizada anterior arrojará un error si el prefijo dado es más corto que toda la cadena. Lo arregló y agregó una optimización de bucle que se puede ver en http://jsperf.com/startswith2/4 .

Tenga en cuenta que hay 2 optimizaciones de bucle que Steve incluyó, la primera de las dos mostró un mejor rendimiento, por lo que publicaré ese código a continuación:

function startsWith2(str, prefix) {
  if (str.length < prefix.length)
    return false;
  for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
    continue;
  return i < 0;
}
Raj Nathani
fuente
Ver la última rev. Además del error en la versión anterior (arrojará si la cadena es más corta que el prefijo), también es más lenta que una versión más optimizada. Consulte jsperf.com/startswith2/4 y jsperf.com/js-startswith/35 .
Steve Hollasch
^ Gracias por señalar el caso donde la cadena es más corta que el prefijo
Raj Nathani
jsperf.com/startswith2/29 => comienzaWith5 es conciso y funciona muy bien =)
gtournie
11

Dado que esto es tan popular, creo que vale la pena señalar que hay una implementación para este método en ECMA 6 y en preparación para eso se debe usar el polyfill 'oficial' para evitar futuros problemas y lágrimas.

Afortunadamente, los expertos de Mozilla nos proporcionan uno:

https://developer.mozilla.org/de/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position) {
        position = position || 0;
        return this.indexOf(searchString, position) === position;
    };
}

Tenga en cuenta que esto tiene la ventaja de ser ignorado con gracia en la transición a ECMA 6.

Scheintod
fuente
5

La mejor solución es dejar de usar las llamadas de la biblioteca y simplemente reconocer que está trabajando con dos matrices. Una implementación manual es corta y también más rápida que cualquier otra solución que he visto aquí.

function startsWith2(str, prefix) {
    if (str.length < prefix.length)
        return false;
    for (var i = prefix.length - 1; (i >= 0) && (str[i] === prefix[i]); --i)
        continue;
    return i < 0;
}

Para las comparaciones de rendimiento (éxito y fracaso), consulte http://jsperf.com/startswith2/4 . (Asegúrese de verificar las versiones posteriores que pueden haber superado la mía).

Steve Hollasch
fuente
2

Acabo de enterarme de esta biblioteca de cadenas:

http://stringjs.com/

Incluya el archivo js y luego use la Svariable como esta:

S('hi there').endsWith('hi there')

También se puede usar en NodeJS instalándolo:

npm install string

Luego requiriéndolo como la Svariable:

var S = require('string');

La página web también tiene enlaces a bibliotecas de cadenas alternativas, si esta no te gusta.

Ashley Davis
fuente
2
  1. La pregunta es un poco antigua, pero quería escribir esta respuesta para mostrarle algunos puntos de referencia que hice en base a todas las respuestas proporcionadas aquí y el jsperf compartido por Jim Buck.

Básicamente necesitaba una forma rápida de encontrar si una aguja larga está dentro de un pajar largo y son muy similares, excepto por los últimos caracteres.

Aquí está el código que he escrito que para cada función (empalme, subcadena, comienza con, etc.) prueba tanto cuando devuelven falso como verdadero contra una cadena de pajar ( nestedString) de 1,000,0001 caracteres y una cadena de aguja falsa o verdadera de 1,000,000 caracteres ( testParentStringFalsey testParentStringTrue, respectivamente):

// nestedString is made of 1.000.001 '1' repeated characters.
var nestedString = '...'

// testParentStringFalse is made of 1.000.000 characters,
// all characters are repeated '1', but the last one is '2',
// so for this string the test should return false.
var testParentStringFalse = '...'

// testParentStringTrue is made of 1.000.000 '1' repeated characters,
// so for this string the test should return true.
var testParentStringTrue = '...'

// You can make these very long strings by running the following bash command
// and edit each one as needed in your editor
// (NOTE: on OS X, `pbcopy` copies the string to the clipboard buffer,
//        on Linux, you would probably need to replace it with `xclip`):
// 
//     printf '1%.0s' {1..1000000} | pbcopy
// 

function testString() {
    let dateStart
    let dateEnd
    let avg
    let count = 100000
    const falseResults = []
    const trueResults = []

    /* slice */
    console.log('========> slice')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.slice(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'slice',
        avg
    }
    console.log(`testString() slice = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== slice')
    console.log('')
    /* slice END */

    /* lastIndexOf */
    console.log('========> lastIndexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringFalse, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.lastIndexOf(testParentStringTrue, 0) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'lastIndexOf',
        avg
    }
    console.log(`testString() lastIndexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== lastIndexOf')
    console.log('')
    /* lastIndexOf END */

    /* indexOf */
    console.log('========> indexOf')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringFalse) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.indexOf(testParentStringTrue) === 0
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'indexOf',
        avg
    }
    console.log(`testString() indexOf = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== indexOf')
    console.log('')
    /* indexOf END */

    /* substring */
    console.log('========> substring')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringFalse.length) === testParentStringFalse
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.substring(0, testParentStringTrue.length) === testParentStringTrue
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'substring',
        avg
    }
    console.log(`testString() substring = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== substring')
    console.log('')
    /* substring END */

    /* startsWith */
    console.log('========> startsWith')
    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringFalse)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    falseResults[falseResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = false`, res, 'avg: ' + avg + 'ms')

    dateStart = +new Date()
    var res
    for (let j = 0; j < count; j++) {
        res = nestedString.startsWith(testParentStringTrue)
    }
    dateEnd = +new Date()
    avg = (dateEnd - dateStart)/count
    trueResults[trueResults.length] = {
        label: 'startsWith',
        avg
    }
    console.log(`testString() startsWith = true`, res, 'avg: ' + avg + 'ms')
    console.log('<======== startsWith')
    console.log('')
    /* startsWith END */

    falseResults.sort((a, b) => a.avg - b.avg)
    trueResults.sort((a, b) => a.avg - b.avg)

    console.log('false results from fastest to slowest avg:', falseResults)
    console.log('true results from fastest to slowest avg:', trueResults)
}

Ejecuté esta prueba de referencia en Chrome 75 , Firefox 67 , Safari 12 y Opera 62 .

No he incluido Edge e IE porque no los tengo en esta máquina, pero si alguien de ustedes quiere ejecutar el script contra Edge y al menos IE 9 y compartir la salida aquí, me daría mucha curiosidad ver los resultados.

Solo recuerde que necesita volver a crear las 3 cadenas largas y guardar el script en un archivo que luego abre en su navegador, ya que copiar / pegar en la consola del navegador lo bloqueará ya que la longitud de cada cadena es> = 1,000,000).

Aquí están las salidas:

Chrome 75 ( substringgana):

false results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08271}
2)  {"label":"slice","avg":0.08615}
3)  {"label":"lastIndexOf","avg":0.77025}
4)  {"label":"indexOf","avg":1.64375}
5)  {"label":"startsWith","avg":3.5454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08213}
2)  {"label":"slice","avg":0.08342}
3)  {"label":"lastIndexOf","avg":0.7831}
4)  {"label":"indexOf","avg":0.88988}
5)  {"label":"startsWith","avg":3.55448}

Firefox 67 ( indexOfgana):

false results from fastest to slowest avg
1)  {"label":"indexOf","avg":0.1807}
2)  {"label":"startsWith","avg":0.74621}
3)  {"label":"substring","avg":0.74898}
4)  {"label":"slice","avg":0.78584}
5)  {"label":"lastIndexOf","avg":0.79668}

true results from fastest to slowest avg:
1)  {"label":"indexOf","avg":0.09528}
2)  {"label":"substring","avg":0.75468}
3)  {"label":"startsWith","avg":0.76717}
4)  {"label":"slice","avg":0.77222}
5)  {"label":"lastIndexOf","avg":0.80527}

Safari 12 ( slicegana por resultados falsos, startsWithgana por resultados verdaderos, también Safari es el más rápido en términos de tiempo total para ejecutar la prueba completa):

false results from fastest to slowest avg:
1) "{\"label\":\"slice\",\"avg\":0.0362}"
2) "{\"label\":\"startsWith\",\"avg\":0.1141}"
3) "{\"label\":\"lastIndexOf\",\"avg\":0.11512}"
4) "{\"label\":\"substring\",\"avg\":0.14751}"
5) "{\"label\":\"indexOf\",\"avg\":0.23109}"

true results from fastest to slowest avg:
1) "{\"label\":\"startsWith\",\"avg\":0.11207}"
2) "{\"label\":\"lastIndexOf\",\"avg\":0.12196}"
3) "{\"label\":\"substring\",\"avg\":0.12495}"
4) "{\"label\":\"indexOf\",\"avg\":0.33667}"
5) "{\"label\":\"slice\",\"avg\":0.49923}"

Opera 62 ( substringgana. Los resultados son similares a los de Chrome y no me sorprende, ya que Opera se basa en Chromium y Blink):

false results from fastest to slowest avg:
{"label":"substring","avg":0.09321}
{"label":"slice","avg":0.09463}
{"label":"lastIndexOf","avg":0.95347}
{"label":"indexOf","avg":1.6337}
{"label":"startsWith","avg":3.61454}

true results from fastest to slowest avg:
1)  {"label":"substring","avg":0.08855}
2)  {"label":"slice","avg":0.12227}
3)  {"label":"indexOf","avg":0.79914}
4)  {"label":"lastIndexOf","avg":1.05086}
5)  {"label":"startsWith","avg":3.70808}

Resulta que cada navegador tiene sus propios detalles de implementación (aparte de Opera, que se basa en Chrome y Blink de Chrome).

Por supuesto, podría y debería realizarse una prueba adicional con diferentes casos de uso (por ejemplo, cuando la aguja es realmente corta en comparación con el pajar, cuando el pajar es más corto que la aguja, etc.), pero en mi caso necesitaba comparar cadenas muy largas y Quería compartirlo aquí.

tonix
fuente
1
var str = 'hol';
var data = 'hola mundo';
if (data.length >= str.length && data.substring(0, str.length) == str)
    return true;
else
    return false;
Chris
fuente
0

Según las respuestas aquí, esta es la versión que estoy usando ahora, ya que parece ofrecer el mejor rendimiento basado en las pruebas de JSPerf (y es funcionalmente completo hasta donde puedo decir).

if(typeof String.prototype.startsWith != 'function'){
    String.prototype.startsWith = function(str){
        if(str == null) return false;
        var i = str.length;
        if(this.length < i) return false;
        for(--i; (i >= 0) && (this[i] === str[i]); --i) continue;
        return i < 0;
    }
}

Esto se basó en beginWith2 desde aquí: http://jsperf.com/startswith2/6 . Agregué un pequeño ajuste para una pequeña mejora en el rendimiento, y desde entonces también agregué una verificación para que la cadena de comparación sea nula o indefinida, y la convertí para agregarla al prototipo de cadena usando la técnica en la respuesta de CMS.

Tenga en cuenta que esta implementación no es compatible con el parámetro "posición" que se menciona en esta página de la Red de desarrolladores de Mozilla , pero de todos modos no parece ser parte de la propuesta de ECMAScript.

Edward Millen
fuente
0

No estoy seguro de JavaScript pero en mecanografiado hice algo como

var str = "something";
(<String>str).startsWith("some");

Supongo que también debería funcionar en js. ¡Espero que ayude!

Andreas Hadjithoma
fuente
-2

Si está trabajando startsWith()y endsWith()debe tener cuidado con los espacios iniciales. Aquí hay un ejemplo completo:

var str1 = " Your String Value Here.!! "; // Starts & ends with spaces    
if (str1.startsWith("Your")) { }  // returns FALSE due to the leading spaces…
if (str1.endsWith("Here.!!")) { } // returns FALSE due to trailing spaces…

var str2 = str1.trim(); // Removes all spaces (and other white-space) from start and end of `str1`.
if (str2.startsWith("Your")) { }  // returns TRUE
if (str2.endsWith("Here.!!")) { } // returns TRUE
immayankmodi
fuente
3
Este es un comportamiento muy no estándar: la cadena "abc" NO comienza con "abc". Más específicamente, ECMA 6 no asume ningún tipo de recorte de cadena, por lo que el espacio en blanco debe coincidir exactamente para producir un inicio con coincidencia.
Steve Hollasch
3
¿Qué ... cómo responde esto a la pregunta?
DCShannon
1
@DCShannon no lo es. Es una tontería incomprensible.
Mark Amery
2
@SteveHollasch Mi intención era conocer a cualquiera que buscara el mismo problema que enfrenté. Que debemos tener cuidado con los espacios iniciales al trabajar con startsWith()y endsWith()funciones. ¡Nada más!
immayankmodi
-3

También puede devolver todos los miembros de una matriz que comienzan con una cadena creando su propio prototipo / extensión al prototipo de matriz, también conocido como

Array.prototype.mySearch = function (target) {
    if (typeof String.prototype.startsWith != 'function') {
        String.prototype.startsWith = function (str){
        return this.slice(0, str.length) == str;
      };
    }
    var retValues = [];
    for (var i = 0; i < this.length; i++) {
        if (this[i].startsWith(target)) { retValues.push(this[i]); }
    }
    return retValues;
};

Y para usarlo:

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
Nepalí
fuente