연결에 왜 +가 나쁜가요?


44

모든 사람들은 JavaScript 문제 중 하나가 문자열 연결에 +[ example ]을 사용하고 있다고 계속 말합니다 . 어떤 사람들은 문제 +가을 사용하지 않는다고 말하고 유형 강제입니다 [이전 예제의 주석 참조]. 그러나 강력한 형식의 언어는 문제없이 연결 및 강제 형식에 +를 사용합니다. 예를 들어 C #에서

int number = 1;
MyObject obj = new MyObject();

var result = "Hello" + number + obj;
// is equivalent to
string result = "hello" + number.ToString() + obj.ToString();

그렇다면 왜 JavaScript에서 문자열 연결이 그렇게 큰 문제입니까?


17
왜이다 bad. 누구 Everyone입니까?
Neal

3
문제는 +가 수학 연산자라고 생각합니다. 그리고 +의 연결 함수는 표준 프로세스를 혼동합니다. "Hello"+ 숫자는 작동 할 수 있지만 "Hello"는 작동하지 않을 수 있기 때문입니다.
SoylentGray

3
@Neal, 나는 동의한다-나는이 모든 신비로운 '모든 것'이이 모든 질문에 누가 있는지 알고 싶다.
GrandmasterB

연결에 +를 사용하는 것이 좋습니다. 동적 입력을 사용하는 것이 좋습니다. 같은 언어로 둘 다 사용하는 것은 나쁘다 ^ H ^ H ^ H는 모호성을 초래한다.
Gerry

6
@Neal- "Everyone"은 Douglas Crockford입니다. 그는 자신의 저서 인 '자바 스크립트 : 좋은 부분들'에 이것을 "awful"로 나열합니다.
kirk.burleson

답변:


68

다음 JavaScript 코드를 고려하십시오.

var a = 10;
var b = 20;
console.log('result is ' + a + b);

이것은 기록합니다

결과는 1020입니다

의도 한 것이 아니며 버그를 추적하기 어려울 수 있습니다.


4
근본적인 문제에 대한 아주 좋은 설명 : 유형 (예에서 문자열 + int + int)이 혼합 될 때 문자열 연결이 잘 정의되어 있지 않습니다. 잘 정의 된 의미를 가진 완전히 다른 연산자 (예 : Perl의 '.')를 갖는 것이 좋습니다.
브루스 Ediger

9
또는이 문제를 해결 파이썬의 방법, 포장을 강제하는 것입니다있는 abstr(a)str(b)통화; 그렇지 않으면을 얻습니다 ValueError: cannot concatenate 'str' and 'int'.
Aphex

6
@FrustratedWithFormsDesigner : 괄호를 추가하십시오. 'result is ' + (a + b).
존 퍼디

18
C #에서는 동일한 작업을 수행 할 수 있으며 동일한 결과를 얻을 수는 System.Console.WriteLine("result is " + 10 + 20);있지만 C #에서는 아무도 불평하지 않습니다. 그것이 내가 이해하지 못하는 것입니다-JavaScript를 더 혼란스럽게 만드는 것은 무엇입니까?
구성자

7
@configurator : 사람들에게 C #이 완벽하고 Javascript가 끔찍하다고 들었 기 때문에. 둘 다 틀렸지 만 언어의 명성이 고수되는 것처럼 보이며, 특히 인터넷에서 인식이 많이 중요합니다.
gbjbaanb

43

"나쁜"이라고 말할 때 "잘못된"또는 "느린"을 의미합니까? 문자열 연결을 수행하기 위해 수학 연산자를 사용하는 것에 대한 논쟁은 틀림없이 "올바르지 않은"논쟁이지만 , 많은 문자열 연결 +을 수행 하는 데 사용 하는 것이 매우 느릴 수 있다는 주장도 있습니다.

우리는 "Hello" + number성능에 대해 이야기 할 때가 아니라 루프에 반복적으로 추가하여 상대적으로 큰 문자열을 만드는 것에 대해 이야기합니다.

var combined = "";
for (var i = 0; i < 1000000; i++) {
    combined = combined + "hello ";
}

JavaScript (및 그 문제에 대한 C #)에서 문자열은 변경할 수 없습니다. 변경할 수 없으며 다른 문자열로만 교체 할 수 있습니다. 변수를 combined + "hello "직접 수정하지 않는다는 것을 알고있을 것입니다. 이 combined작업은 두 문자열을 연결 한 결과로 새 문자열을 생성하지만 combined변수를 변경 하려면 해당 새 문자열을 변수에 할당해야합니다 .

이 루프가하는 일은 백만 개의 다른 문자열 객체를 만들어 999,999 개를 버리는 것입니다. 지속적으로 크기가 커지는 많은 문자열을 만드는 것은 빠르지 않으며 이제 가비지 수집기는 이후에 정리해야 할 많은 작업이 있습니다.

C #은 똑같은 문제가 있는데, 이는 해당 환경에서 StringBuilder 클래스에 의해 해결됩니다 . JavaScript에서는 연결하려는 모든 문자열의 배열을 구성한 다음 루프에서 백만 번이 아니라 마지막에 한 번에 결합하여 성능이 훨씬 향상됩니다.

var parts = [];
for (var i = 0; i < 1000000; i++) {
    parts.push("hello");
}
var combined = parts.join(" ");

3
이것은 훌륭한 답변입니다. 질문에 대답했을뿐 아니라 교육을 받았습니다.
Charles Sprayberry

3
이것은 내가 의미하는 바가 아니며 질문과 완전히 관련이 없습니다.
구성자

4
죄송합니다. 7 명 이상이 귀하의 질문을 말한 방식으로 오해 한 것 같습니다.
Joel Mueller

9
재 성능 : 아마도 2011 년의 경우 였지만 이제 + 연산자 메소드는 array.join 메소드 (최소한 v8)보다 훨씬 빠릅니다. 이 jsperf를 참조하십시오 jsperf.com/string-concatenation101
UpTheCreek

2
조인 방법이 하나의 단계에서 여러 부분으로 하나의 문자열을 생성하는 방법에 대한 아이디어가 하나씩 조합되어 모든 중간 문자열을 생성하는 방법은 무엇입니까?
Angelo.Hannes

14

숫자 만 추가하고 문자열 만 연결할 수 있다면 더하기와 연결 모두에 +를 사용하는 것은 나쁘지 않습니다. 그러나 Javascript는 필요에 따라 숫자와 문자열을 자동으로 변환하므로 다음이 있습니다.

3 * 5 => 15
"3" * "5" => 15
2 + " fish" => "2 fish"
"3" + "5" => "35"  // hmmm...

아마도 더 간단하게는 자동 유형 변환이있을 때 "+"를 오버로드하면 + 연산자의 예상 연관성이 깨집니다.

("x" + 1) + 3 != "x" + (1 + 3)

2
또한 추가의 3 + 5 == 5 + 3"3" + "5" != "5" + "3"
계산적

10

문자열 연결에 대한 일반적인 문제는 다음과 같은 몇 가지 문제와 관련이 있습니다.

  1. +과부하 된 기호
  2. 간단한 실수
  3. 게으른 프로그래머

#1

사용과 함께 가장 먼저 문제 +문자열 연결 하고 또한 당신이 사용하고 있다는 점이다 +문자열 연결 추가.

당신이 변수가있는 경우 ab, 당신은 설정 c = a + b의 종류에 따라 모호한 존재 a하고 b. 이 모호성으로 인해 문제를 완화하기 위해 추가 단계를 수행해야합니다.

문자열 연결 :

c = '' + a + b;

부가:

c = parseFloat(a) + parseFloat(b);

이것은 나의 두 번째 요점을 알려줍니다

# 2

실수로 변수를 인식하지 않고 문자열로 캐스팅하는 것은 매우 쉽습니다. 입력이 문자열로 오는 것을 잊어 버리는 것도 쉽습니다.

a = prompt('Pick a number');
b = prompt('Pick a second number');
alert( a + b );

프롬프트가 입력의 문자열 값을 반환하기 때문에 직관적이지 않은 결과를 생성합니다.

#삼

입력해야 할 parseFloat때나 Number()추가를 원할 때마다 번거롭고 성가신 일입니다. 나는 내 동적 유형을 엉망으로 만들지 않는 것을 기억할만큼 똑똑하다고 생각하지만 내 동적 유형을 엉망으로 만들지 않았다는 것을 의미하지는 않는다 . 문제의 진실은 내가 많은 것을 추가 하기 때문에 내가 타자를 입력 할 때마다 parseFloat또는 Number()내가 추가 할 때마다 너무 게으르다 는 것입니다.

해결책?

모든 언어 +가 문자열 연결에 사용 되는 것은 아닙니다 . PHP는 .문자열을 연결하는 데 사용하므로 숫자를 추가 할 때와 문자열을 결합 할 때를 구별하는 데 도움이됩니다.

문자열을 연결하는 데 모든 기호를 사용할 수 있지만 대부분 이미 사용 된 것이기 때문에 복제를 피하는 것이 가장 좋습니다. 내가 길을 가졌다면 아마도 _문자열을 조인 _하고 변수 이름을 허용하지 않을 것입니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.