IT story

JavaScript 문자열은 변경할 수 없습니까?

hot-time 2020. 4. 24. 08:09
반응형

JavaScript 문자열은 변경할 수 없습니까? JavaScript에서 "문자열 작성기"가 필요합니까?


자바 스크립트는 변경 불가능하거나 변경 가능한 문자열을 사용합니까? "문자열 작성기"가 필요합니까?


그들은 불변이다. 문자열 내에서와 같은 문자를 변경할 수 없습니다 var myString = "abbdef"; myString[2] = 'c'. 같은 문자열 조작 방법 trim, slice새로운 문자열을 반환합니다.

같은 방식으로 동일한 문자열에 대한 두 개의 참조가있는 경우 하나를 수정해도 다른 하나에는 영향을 미치지 않습니다.

let a = b = "hello";
a = a + " world";
// b is not affected

그러나 Ash의 답변에서 Array.join을 사용하면 연결 속도가 더 빠릅니다. 이것이 사실인지 확인하기 위해 몇 가지 테스트를 작성했습니다 (그렇지 않습니다!).

메서드 호출을 추가하면 속도가 느려질 수 있다고 생각했지만 이것이 가장 빠른 방법이라고 생각했습니다.

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

성능 속도 테스트는 다음과 같습니다. 세 사람 모두 "Hello diggity dog"10 만 번의 빈 줄로 연결된 거대한 줄을 만듭니다 .

세 가지 유형의 테스트를 만들었습니다

  • 사용 Array.push하여Array.join
  • 피하기 위해 배열 인덱싱 Array.push사용Array.join
  • 직선 연결

그럼 난로를 추출하여 같은 세 가지 테스트를 생성 StringBuilderConcat, StringBuilderArrayPush그리고 StringBuilderArrayIndex http://jsperf.com/string-concat-without-sringbuilder/5 우리가 좋은 샘플을 얻을 수 있도록 가서 실행 테스트하십시오. 작은 버그를 수정 했으므로 테스트 데이터가 지워졌으므로 성능 데이터가 충분하면 테이블을 업데이트합니다. 이전 데이터 테이블은 http://jsperf.com/string-concat-without-sringbuilder/5이동 하십시오.

링크를 따르고 싶지 않은 경우 일부 숫자 (Ma5rch 2018의 최신 업데이트)가 있습니다. 각 테스트의 숫자는 초당 1000 회입니다 ( 높을수록 좋습니다 ).

| Browser          | Index | Push | Concat | SBIndex | SBPush | SBConcat |
---------------------------------------------------------------------------
| Chrome 71.0.3578 | 988   | 1006 | 2902   | 963     | 1008   | 2902     |
| Firefox 65       | 1979  | 1902 | 2197   | 1917    | 1873   | 1953     |
| Edge             | 593   | 373  | 952    | 361     | 415    | 444      |
| Exploder 11      | 655   | 532  | 761    | 537     | 567    | 387      |
| Opera 58.0.3135  | 1135  | 1200 | 4357   | 1137    | 1188   | 4294     | 

결과

  • 오늘날 모든 상록 브라우저는 문자열 연결을 잘 처리합니다. Array.joinIE 11에만 도움

  • 전반적으로 Opera는 Array.join보다 4 배 빠릅니다.

  • Firefox는 두 번째이며 Array.joinFF에서는 약간 느리지 만 Chrome에서는 상당히 느립니다 (3 배).

  • 크롬은 세 번째이지만 문자열 연결은 Array.join보다 3 배 빠릅니다.

  • StringBuilder를 만드는 것은 성능에 큰 영향을 미치지 않는 것 같습니다.

다른 사람이 유용하다고 생각하기를 바랍니다.

다른 테스트 사례

@RoyTinker는 내 테스트에 결함이 있다고 생각했기 때문에 동일한 문자열을 연결하여 큰 문자열을 만들지 않는 새로운 사례를 만들었습니다. 각 반복마다 다른 문자를 사용합니다. 문자열 연결은 여전히 ​​더 빠르거나 빠릅니다. 테스트를 실행 해 봅시다.

나는 모든 사람들이 이것을 테스트하는 다른 방법을 계속 생각하고 아래의 다른 테스트 사례에 새로운 링크를 자유롭게 추가 할 것을 제안합니다.

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


로부터 코뿔소 책 :

JavaScript에서 문자열은 변경할 수없는 개체이므로 문자열 내의 문자가 변경되지 않고 문자열에 대한 작업이 실제로 새 문자열을 만듭니다. 문자열은 값이 아니라 참조로 지정됩니다. 일반적으로 객체가 참조로 할당되면 하나의 참조를 통해 객체에 대한 변경 사항은 객체에 대한 다른 모든 참조를 통해 볼 수 있습니다. 그러나 문자열을 변경할 수 없기 때문에 문자열 객체에 대한 여러 참조를 가질 수 있으며 문자열 값을 몰라도 문자열 값이 변경 될 염려가 없습니다


성능 팁 :

큰 문자열을 연결해야하는 경우 문자열 부분을 배열에 넣고 Array.Join()메서드를 사용 하여 전체 문자열을 가져옵니다. 이것은 많은 수의 문자열을 연결하는 데 몇 배 더 빠를 수 있습니다.

StringBuilderJavaScript 에는 없습니다 .


내 것과 같은 간단한 마음을 분명히하기 위해 ( MDN 출신 ) :

불변은 객체가 생성되면 상태를 변경할 수없는 객체입니다.

문자열과 숫자는 변경할 수 없습니다.

불변은 다음을 의미합니다.

변수 이름이 새 값을 가리 키도록 할 수 있지만 이전 값은 여전히 ​​메모리에 유지됩니다. 따라서 가비지 수집이 필요합니다.

var immutableString = "Hello";

// 위 코드에서 문자열 값을 가진 새 객체가 생성됩니다.

immutableString = immutableString + "World";

// "World"를 기존 값에 추가합니다.

문자열 'immutableString'을 변경하는 것처럼 보이지만 그렇지 않습니다. 대신 :

"immutableString"에 문자열 값을 추가하면 다음과 같은 이벤트가 발생합니다.

  1. "immutableString"의 기존 값이 검색됩니다.
  2. "World"는 기존의 "immutableString"값에 추가됩니다.
  3. 그런 다음 결과 값이 새 메모리 블록에 할당됩니다.
  4. "immutableString"오브젝트가 이제 새로 작성된 메모리 공간을 가리킴
  5. 이전에 작성된 메모리 공간을 이제 가비지 콜렉션에 사용할 수 있습니다.

문자열 유형 값은 변경할 수 없지만 String () 생성자를 사용하여 만든 String 개체는 개체이므로 새 속성을 추가 할 수 있으므로 변경할 수 있습니다.

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

한편 새 속성을 추가 할 수 있지만 기존 속성을 변경할 수는 없습니다

Chrome 콘솔 테스트의 스크린 샷

결론적으로, 1. 모든 문자열 타입 값 (primitive type)은 불변이다. 2. String 객체는 변경 가능하지만 포함 된 문자열 유형 값 (기본 유형)은 변경할 수 없습니다.


문자열은 변경할 수 없습니다. 변경할 수 없으며 새로운 문자열 만 만들 수 있습니다.

예:

var str= "Immutable value"; // it is immutable

var other= statement.slice(2, 10); // new string

ASP.NET Ajax의 StringBuilder에 대한 귀하의 의견 (Ash의 답변에 대한 귀하의 의견)에 관해서 전문가들은 이에 동의하지 않는 것 같습니다.

Christian Wenz는 자신의 저서 Programming ASP.NET AJAX (O'Reilly)에서 "이 접근 방식은 메모리에 측정 가능한 영향을 미치지 않습니다 (사실 구현은 표준 접근 방식보다 속도가 느립니다)"고 말합니다.

반면 Gallo 등은 자신의 저서 인 ASP.NET AJAX in Action (Manning)에서 "연결할 문자열의 수가 더 많을 때, 문자열 작성기는 큰 성능 저하를 피하기위한 필수 개체가된다"고 말합니다.

자체 벤치마킹을 수행해야하며 브라우저마다 결과가 다를 수 있습니다. 그러나 성능이 향상되지 않더라도 C # 또는 Java와 같은 언어로 StringBuilder로 코딩하는 데 익숙한 프로그래머에게는 여전히 "유용한"것으로 간주 될 수 있습니다.


늦은 게시물이지만 답변 중에서 좋은 책 인용문을 찾지 못했습니다.

믿을만한 책을 제외하고는 분명합니다.

ECMAScript에서는 문자열을 변경할 수 없습니다. 즉, 일단 생성 한 후에는 값을 변경할 수 없습니다. 변수에 포함 된 문자열을 변경하려면 원래 문자열을 삭제하고 변수에 새 값을 포함하는 다른 문자열로 채워야합니다. — Professional JavaScript for Web Developers, 3rd Ed., p.43

이제 Rhino 서적 발췌문을 인용 한 답은 문자열 불변성에 대해서는 맞지만 "문자열은 값이 아니라 참조로 할당됩니다"라는 잘못된 말입니다. (아마도 그들은 원래 단어를 반대 방향으로 놓는 것을 의미했습니다).

"참조 / 값"오해는 "기본 및 참조 값"이라는 "전문 JavaScript"장에서 설명됩니다.

다섯 가지 기본 유형 ... [정의되지 않음, Null, 부울, 숫자 및 문자열]. 변수에 저장된 실제 값을 조작하기 때문에 이러한 변수는 값으로 액세스한다고합니다. — 웹 개발자를위한 전문 JavaScript, 3rd Ed., p.85

그것은 객체와 반대입니다 .

객체를 조작 할 때 실제 객체 자체가 아니라 해당 객체에 대한 참조 작업을하고 있습니다. 이러한 이유로, 이러한 값은 참조로 액세스한다고합니다. — 웹 개발자를위한 전문 JavaScript, 3rd Ed., p.85


JavaScript 문자열은 실제로 변경할 수 없습니다.


Javascript의 문자열은 변경할 수 없습니다

참고 : https://stackoverflow.com/questions/51185/are-javascript-strings-immutable-do-i-need-a-string-builder-in-javascript

반응형