문자열이 다른 문자열 "StartsWith"인지 확인하는 방법은 무엇입니까?


1690

String.StartsWithJavaScript에서 C #과 동등한 것을 어떻게 작성 합니까?

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

haystack.startsWith(needle) == true

참고 : 이것은 오래된 질문이며, ECMAScript 2015 (ES6)는이 .startsWith방법을 도입 한 의견에서 지적한 바와 같습니다 . 그러나이 업데이트 (2015)를 작성할 당시 브라우저 지원은 아직 완료되지 않았습니다 .

답변:


1773

ECMAScript 6의 String.prototype.startsWith()방법을 사용할 수 있지만 아직 모든 브라우저에서 지원되는 것은 아닙니다 . shim / polyfill을 사용하여 지원하지 않는 브라우저에 추가 할 수 있습니다. 사양에 제시된 모든 세부 사항 을 준수하는 구현을 만드는 것은 약간 복잡합니다. 충실한 심을 원한다면 다음 중 하나를 사용하십시오.

메소드를 숨기면 (또는 이미있는 브라우저 및 JavaScript 엔진 만 지원하는 경우) 다음과 같이 사용할 수 있습니다.

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

var haystack = "Hello world";
var prefix = 'orl';
haystack.startsWith(prefix); // false

@gtournie 왜 문자열이 문자열로 시작하는지 테스트하는 최악의 방법 중 하나가 될까요? (여기서 의견 : stackoverflow.com/questions/646628/… ) 문자 당 문자를 비교하는 데 더 열정적입니다. 나는 컴파일러가 모든 문자열 [인덱스]에 대해 문자열을 생성하지 않을 정도로 똑똑하기를 바란다. 왜냐하면 단순히 이것을 쓰면 : character = string [0] 객체를 할당 할 것이고, startsWith를 사용하는 것보다 무한히 효율적이다. )
Martijn Scheffer

@MartijnScheffer : 대답은 내가 대답 한 이후 여러 번 편집되었으며 이제 완전히 다릅니다 (내 의견을 제거했습니다;). ECMAScript 6의 startsWith 메소드가 가장 좋은 방법이라는 데 동의합니다.
gtournie

6
@GrahamLaight, 'IE'에서 지원한다고 말할 때 아마도 Edge를 의미합니다. developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Marcus

@Marcus, 내가 틀렸다면 사과드립니다. 내 정보는 다음에서 제공됩니다 : w3schools.com/jsref/jsref_startswith.asp
Graham Laight

경고! 이 jsperf 테스트는 JIT 컴파일에 능숙한 브라우저에서는 작동하지 않습니다. Firefox 및 Chrome과 같은 브라우저 는 작업 결과가 삭제 될 때이를 인식하여 작업을 수행하지 않습니다 . 그 외에도 현대 자바 스크립트 엔진은 분기 예측을 사용 하므로 테스트 문자열은 각 반복마다 달라야합니다.
Aloso

1282

다른 대안 .lastIndexOf:

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

이를 뒤로 보이는 haystack의 발생에 대한 needle인덱스부터 0haystack. 즉,로 haystack시작 하는지 만 확인합니다 needle.

원칙적으로 다른 접근 방식에 비해 성능 이점이 있어야합니다.

  • 전체를 검색하지는 않습니다 haystack.
  • 새로운 임시 문자열을 생성하지 않고 즉시 버립니다.

1
- 확실하지 rfcoder89 @하는 경우에 대해 취하고있다 jsfiddle.net/jkzjw3w2/1
Gulfaraz 라만

5
@ rfcoder89 lastIndexOf :의 두 번째 매개 변수는 "aba".lastIndexOf ("a")지적했듯이 2이지만 "aba".lastIndexOf ("a", 0)0입니다.
maxpolk

1
정말 고맙습니다. String.startsWith는 Android 롤리팝 WebView에서 작동하지 않지만이 lastIndexOf 스 니펫은 작동하지 않습니다!
허먼

lastIndexOf에서도 문자열은 전체 문자열을 검색하도록 처음으로 끝에서 검색되어 그 효율성이 매우 긴 문자열을 성장 있도록에서 검색 할 수 있습니다.
윌리 wonka

8
@willywonka 아니요, 0 startIndex가 없으면 0 위치에서 검색되며 유일한 확인입니다. fromIndex> = str.length 인 경우에만 전체 문자열을 검색합니다.
greene

588
data.substring(0, input.length) === input

3
@ ANeves 브라우저와 사용 된 데이터에 크게 의존한다고 생각합니다. 실제 측정에 대해서는 Ben Weaver의 답변을 참조하십시오. 브라우저에서 현재 실행 중입니다 (Windows의 Chrome 12.0.742) 하위 문자열이 성공을 위해 승리하고 준비된 정규식이 실패를 위해 승리합니다.
cobbal

4
@cobbal 아마도. 그러나 .lastIndexOf(input, 0)첫 번째 N 문자를 비교하고 N을 .substring(0, input.length) === input계산하고 데이터를 N 길이로 하위 문자열로 묶은 다음 해당 N 문자를 비교합니다. 코드 최적화가 없으면이 두 번째 버전은 다른 버전보다 빠를 수 없습니다. 그래도 오해하지 마십시오. 나는 당신이 제안한 것보다 더 나은 것을 스스로 찾지 못할 것입니다. :)
ANeves

2
@ANeves 그러나 false를 반환하는 긴 문자열에서 .lastIndexOf는 전체 문자열 (O (N))을 반복하는 반면 .substring 케이스는 잠재적으로 훨씬 작은 문자열을 반복합니다. 대부분의 성공 또는 작은 입력 만 예상하는 경우 .lastIndexOf가 더 빠를 수 있습니다. 그렇지 않으면 .substring이 더 빠릅니다. .substring은 입력이 점검중인 문자열보다 길면 예외의 위험이 있습니다.
Chris Moschini

14
@ChrisMoschini, Mark Byers의 솔루션이 lastIndexOf끝이 아닌 인덱스 0에서 시작 한다는 것을 잊지 마십시오 . 처음에는 저를 넘어 뜨 렸습니다. 여전히 문자열로 시작하는 것을 확인하는 것은 JavaScript가 실제로 적절한 API를 가져야하는 일반적인 작업이지만,이 페이지에서 볼 수있는 모든 관용구와 대안은 아니지만 현명합니다.
랜달 쿡

4
Mark보다 Cobbal의 솔루션을 선호합니다. 마크가 빠르고 매개 변수를 사용하는 인상적인 트릭이더라도 하위 문자열에 비해 읽기가 매우 어렵습니다.
ThinkBonobo

184

도우미 함수가 없으면 정규식 .test방법을 사용하십시오.

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

하드 코드 된 문자열이 아닌 동적 문자열로이를 수행하려면 (문자열에 정규식 제어 문자가 포함되지 않는다고 가정) :

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

Javascript에 RegExp.escape 함수가 있습니까?를 확인하십시오 . regexp 제어 문자가 문자열에 나타날 가능성이있는 경우


1
대소 문자를 구분하여 표현식을 사용하려면/^he/i
kaizer1v

64

최고의 솔루션 :

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

그리고 여기에도 이 있습니다.

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

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;
});

용법:

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

방법으로 :

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

함수에서 lastIndexOf와 indexOf를 혼합했다고 생각합니다. startsWith는 return str.indexOf (word, 0) === 0;
Richard Matheson

5
@RichardMatheson indexOf를 사용할 때의 문제점은 시작시 일치하지 않으면 전체 문자열을 계속 검색하므로 lastIndexOf는 단어의 길이에서 시작하여 0으로 되돌아갑니다. 알았다?
mmm

2
아 네, 이제 이해가됩니다-나는 당신이 사용하고있는 지수에주의를 기울이지 않았습니다. 아주 좋은 트릭!
Richard Matheson 2012

54

나는 이것에 대한 나의 의견을 추가하고 싶었다.

우리는 다음과 같이 사용할 수 있다고 생각합니다.

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

if (haystack.indexOf(needle) == 0) {
  // Code if string starts with this substring
}

2
Mark Byers의 답변은 @relfor의 세 가지 올바른 접근 방식의 성능과 비교되었습니다. 이 올바른 접근 방식은 전체 문자열을 검색해야하기 때문에 선호되지 않았습니다.
maxpolk

@ maxpolk indexOf첫 번째 문자열을 발견하면 전체 문자열 검색을 중지합니다. 확인했습니다.
Mr.D

8
처음에 첫 번째 항목이 발견되지 않으면이 방법은 검색 시간이 길어질수록 비효율적으로 커지기 시작하여 잠재적으로 훨씬 빨리 포기하지 않고 끝까지 도달 할 수 있습니다. 비효율의 가능성이 있기 때문에 세 가지 올바른 접근 방식 중에서 선호되지 않습니다.
maxpolk 2016 년

2
@ Mr.D 그리고 일치하는 것이 없다면?
mmm

그렇지 않으면 모든 건초 더미가 검색되었을 때? 더 나은 : stackoverflow.com/a/36876507/961018 .. 최대 단어 길이 만 검색
mmm

39

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

향후 브라우저가 원시 코드로 기능을 구현하거나 다른 라이브러리에 의해 구현되는지 여부에 따라 기능이 이미 존재하는지 확인 예를 들어, 프로토 타입 라이브러리는이 기능을 이미 구현합니다.

읽을 수 !=== 0없지만 사용하는 것이 약간 더 빠르고 간결 합니다.


1
이것은 문제가 될 수 있습니다 : 구현이 이미 제 자신과 다르게 작동하면 응용 프로그램이 손상됩니다.
Christoph Wurm

2
이것은 O는 (N) 문제가 여기에 설명이 stackoverflow.com/questions/646628/javascript-startswith/...
크리스 Moschini

1
사용! 매우 지저분하다
JonnyRaa

-1; 에 String.prototype대한 사양 을 준수하는 위치에 오지 않기 때문에 이것을 추가 하는 것은 나쁜 생각 입니다 String.prototype.startsWith. ES6 메소드를 사용하려고 시도하는 모든 코드는이 작업을 수행하면 실패 할 수 있습니다. 메소드가 이미 정의되어 있는지 확인하고, 메소드가 (나쁘게) 정의되어 있고 사양 호환 shim을 추가하지 않아 나중에 잘못된 동작이 발생할 수 있습니다.
Mark Amery

21

underscore.string.js 도 확인하십시오 . 메소드를 포함하여 유용한 문자열 테스트 및 조작 startsWith방법이 많이 있습니다. 문서에서 :

로 시작 _.startsWith(string, starts)

이 방법 string은로 시작 하는지 확인합니다 starts.

_("image.gif").startsWith("image")
=> true

1
내가 필요_.string.startsWith
패닉 대령

15

나는 최근에 나에게 같은 질문을했다.
여러 가지 가능한 솔루션이 있습니다. 여기에는 3 가지 유효한 솔루션이 있습니다.

  • s.indexOf(starter) === 0
  • s.substr(0,starter.length) === starter
  • s.lastIndexOf(starter, 0) === 0(Mark Byers의 답변 을 본 후 추가됨 )
  • 루프를 사용하여 :

    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;
    }

루프를 사용하는 마지막 솔루션을 보지 못했습니다.
놀랍게도이 솔루션은 첫 번째 3보다 큰 차이를 보입니다.
이 결론에 도달하기 위해 수행 한 jsperf 테스트는 다음과 같습니다. http://jsperf.com/startswith2/2

평화

추신 : ecmascript 6 (하모니) startsWith은 문자열에 대한 기본 방법을 소개합니다 .
초기 버전 자체에 필요한 방법을 많이 포함시킬 생각이라면 얼마나 많은 시간이 절약 될지 생각해보십시오.

최신 정보

Steve가 지적했듯이 (이 답변의 첫 번째 주석) 주어진 접두사 가 전체 문자열보다 짧은 경우 위의 사용자 정의 함수에서 오류가 발생 합니다. 그는 그것을 고치고 http://jsperf.com/startswith2/4 에서 볼 수있는 루프 최적화를 추가했습니다 .

Steve가 포함 한 2 개의 루프 최적화가 있으며 두 가지 중 첫 번째가 더 나은 성능을 보였으므로 아래 코드를 게시합니다.

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;
}

최신 개정판을 참조하십시오. 위 버전의 버그 외에도 (문자열이 접두사보다 짧은 경우 발생합니다) 최적화 된 버전보다 느립니다. jsperf.com/startswith2/4jsperf.com/js-startswith/35를 참조하십시오 .
Steve Hollasch

^ 문자열이 접두사보다 짧은 경우를 지적 해 주셔서 감사합니다
Raj Nathani

jsperf.com/startswith2/29 => startsWith5는 간결하고 정말 잘 수행합니다 =)
gtournie

11

이것이 매우 인기가 있기 때문에 ECMA 6에는이 방법에 대한 구현이 있으며 미래의 문제와 눈물을 막기 위해 '공식적인'폴리 필을 사용해야한다는 점을 지적 할 가치가 있다고 생각합니다.

운 좋게도 모질라 전문가들이 우리에게 다음을 제공합니다.

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;
    };
}

이는 ECMA 6으로 전환 할 때 정상적으로 무시되는 이점이 있습니다.


5

최상의 성능을 발휘하는 솔루션은 라이브러리 호출 사용을 중단하고 두 개의 어레이로 작업하고 있다는 것을 인식하는 것입니다. 수동 구현은 여기서 본 다른 모든 솔루션보다 짧고 빠릅니다.

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;
}

성능 비교 (성공 및 실패)는 http://jsperf.com/startswith2/4를 참조하십시오 . (나보다 먼저 나올 수있는 이후 버전을 확인하십시오.)


2

이 문자열 라이브러리에 대해 방금 배웠습니다.

http://stringjs.com/

js 파일을 포함시키고 다음 S과 같이 변수 를 사용하십시오 .

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

NodeJS에서 설치하여 사용할 수도 있습니다.

npm install string

그런 다음 S변수 로 요구하십시오 .

var S = require('string');

웹 페이지에는 다른 문자열 라이브러리에 대한 링크가 있습니다.


2
  1. 질문은 조금 오래되었지만 여기에 제공된 모든 답변과 Jim Buck이 공유 한 jsperf를 기반으로 한 벤치 마크를 보여주기 위해이 답변을 작성하고 싶었습니다.

기본적으로 긴 바늘이 긴 건초 더미 내에 있는지 확인하는 마지막 방법이 필요했으며 마지막 문자를 제외하고는 매우 유사합니다.

다음은 각 함수 (splice, substring, startsWith 등)에 대해 nestedString1.000.0001 문자 의 건초 더미 문자열 ( )과 1.000.000의 거짓 또는 진실 바늘 문자열에 대해 false와 true를 반환 할 때 테스트 하는 코드입니다. 문자 ( testParentStringFalsetestParentStringTrue각각) :

// 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)
}

Chrome 75 , Firefox 67 , Safari 12Opera 62 에서이 벤치 마크 테스트를 실행했습니다. .

이 컴퓨터에 Edge와 IE가 포함되어 있지 않기 때문에 Edge와 IE를 포함시키지 않았지만 누군가 누군가 Edge와 적어도 IE 9에 대해 스크립트를 실행하고 출력을 여기에서 공유하고 싶다면 결과가 궁금합니다.

3 개의 긴 문자열을 다시 작성하고 스크립트를 파일에 저장 한 다음 브라우저 콘솔에서 복사 / 붙여 넣기로 브라우저에서 열면 각 문자열의 길이가> = 1.000.000)이므로 차단해야합니다.

출력은 다음과 같습니다.

크롬 75 ( substring승) :

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 ( indexOf승) :

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 ( slice실수 결과, startsWith승리, 실제 결과 승리, Safari는 전체 테스트를 수행하는 데 걸리는 총 시간 측면에서 가장 빠름) :

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 ( substring승. 결과는 Chrome과 유사하며 Opera가 Chromium 및 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}

모든 브라우저에는 자체 구현 세부 정보가 있습니다 (Chrome의 Chromium 및 Blink를 기반으로하는 Opera 제외).

물론 다른 유스 케이스로 추가 테스트를 수행 할 수 있고 수행해야합니다 (예 : 바늘이 건초 더미에 비해 실제로 짧은 경우, 건초 더미가 바늘보다 짧은 경우 등).하지만 제 경우에는 매우 긴 줄을 비교해야했습니다. 여기에 공유하고 싶었습니다.


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

0

여기에 대한 답변을 바탕으로 JSPerf 테스트를 기반으로 최고의 성능을 제공하는 것 같습니다 (그리고 내가 말할 수있는 한 기능적으로 완벽합니다).

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;
    }
}

이것은 startsWith2를 기반으로합니다 : http://jsperf.com/startswith2/6 합니다. 약간의 성능 향상을 위해 약간의 조정을 추가 한 후 비교 문자열이 null인지 정의되지 않았는지 확인하고 CMS의 답변 기술을 사용하여 문자열 프로토 타입에 추가하도록 변환했습니다.

이 구현은이 Mozilla 개발자 네트워크 페이지 에서 언급 된 "position"매개 변수를 지원 하지 않지만 ECMAScript 제안의 일부는 아닌 것 같습니다.


0

나는 자바 스크립트에 대해 확실하지 않지만 typescript에서 나는 다음과 같은 것을했다.

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

js에서도 작동해야한다고 생각합니다. 도움이 되길 바랍니다!


-2

당신이 작업하는 경우 startsWith()그리고 endsWith()당신은 선행 공백에주의해야한다. 다음은 완전한 예입니다.

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

3
이는 매우 비표준 동작입니다. "abc"문자열은 "abc"로 시작하지 않습니다. 보다 구체적으로, ECMA 6은 어떤 종류의 문자열 트리밍을 가정하지 않으므로, 공백이 정확히 일치하여 startsWith와 일치해야합니다.
Steve Hollasch

3
이 질문에 어떻게 대답합니까?
DCShannon

1
@DCShannon 그렇지 않습니다. 이해할 수없는 말도 안됩니다.
Mark Amery 1

2
@SteveHollasch 내 의도는 내가 직면 한 동일한 문제를 찾는 사람을 아는 것이 었습니다. 작업 startsWith()endsWith()기능을 수행 할 때 선행 공백에주의해야 합니다. 다른 것은 없습니다!
immayankmodi 12

-3

또한 배열 프로토 타입에 대한 고유 한 프로토 타입 / 확장명을 만들어 문자열로 시작하는 배열의 모든 멤버를 반환 할 수도 있습니다.

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;
};

그리고 그것을 사용하려면 :

var myArray = ['Hello', 'Helium', 'Hideout', 'Hamster'];
var myResult = myArray.mySearch('Hel');
// result -> Hello, Helium
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.