JavaScript에서 증가 (“++”) 및 감소 (“-”) 연산자를 피해야하는 이유는 무엇입니까?


357

jslint 도구 중 하나 는 다음과 같습니다.

++ 및-
++ (증가) 및-(감소) 연산자는 과도한 까다 로움을 유발하여 잘못된 코드에 기여하는 것으로 알려져 있습니다. 바이러스 및 기타 보안 위협을 가능하게하는 잘못된 아키텍처에 이어 두 번째입니다. 이 연산자의 사용을 금지하는 플러스 플러스 옵션이 있습니다.

나는 PHP 구문 $foo[$bar++]이 쉽게 하나의 오류로 인해 발생할 수 있다는 것을 알고 있지만 a while( a < 10 ) do { /* foo */ a++; }또는 보다 루프를 제어하는 ​​더 좋은 방법을 알 수는 없습니다 for (var i=0; i<10; i++) { /* foo */ }.

" ++"및 " --"구문 이없는 유사한 언어가 있거나 다르게 처리하거나, " ++"및 " --" 를 피할 수있는 다른 근거가 있기 때문에 jslint가 강조 표시 합니까?


59
따라서 array [++ index] 대신 array [index = index + 1]을 수행해야합니다. 후이의 짐.
Lawrence Dol 2016 년

34
Crockford가 index = index + 1을하는 것을 보지 못했습니다. 나는 그가 인덱스 + 1을하는 것을 보았습니다. 나는 그것이 합리적인 대안이라고 생각합니다. 보폭을 1 이외의 것으로 변경하고 싶을 때 유용합니다.
Nosredna

124
개인적으로 저는 Crockford의 열렬한 팬이 아닙니다. 그는 자신의 코드에서 버그를 유발 한 모든 것을 사악한 것으로 간주합니다.
Paolo Bergantino 2016 년

38
JavaScript에서는 공식적인 문서가없고, 인증서 제공 업체도없고, 대학에서 JS를 제대로 배우지 못하기 때문에 모든 버그를 다소 악의적 인 것으로 간주해야합니다. Crockford와 Firebug는 JavaScript 교육에서 이러한 허점을 채웠습니다.
stevek

40
++버그를 일으키지 않습니다. ++"두려운"방식으로 사용하면 버그가 발생할 수 있습니다 . 특히 둘 이상의 사람이 코드베이스를 유지 관리하는 경우에는 운영자의 문제가 아니라 프로그래머의 문제입니다. 나는 아직 존재하지 않았기 때문에 대학에서 JS를 배우지 못했지만 어떻게해야합니까? 물론 C를했는데, 물론 ++첫 번째로 "그렇게 무엇을 얻습니까?" 나는 특정 언어를 배우기 위해 대학에 가지 않았고, 어떤 언어 에도 적용 할 수있는 좋은 프로그래밍 실습을 배우러 갔다 .
nnnnnn

답변:


408

내 견해는 항상 ++를 사용하는 것입니다.

i++;
array[i] = foo;

대신에

array[++i] = foo;

그 이외의 것은 프로그래머에게 혼란을 줄 수 있으며 내 견해로는 가치가 없습니다. 증분 연산자의 사용은 관용적이므로 항상 명확하므로 For 루프는 예외입니다.


3
그래, 나도 그래 잘못하기가 어렵고 다른 사람들이 자신이하는 일을 쉽게 파악할 수 있습니다.
Nosredna 2016 년

65
그것은 문제의 핵심과 혼란을 겪고있는 것 같습니다. 단독으로 사용, i ++; 명백하다. 기본 표현, 가독성 및 선명도를 중심으로 다른 코드를 추가하는 순간부터 시작됩니다.
artlung

2
동의하지만 JavaScript에만 관련되는 것은 아닙니다
Tobias

5
C 또는 C ++를 작성하는지 여부는 말하지 않습니다. i변수가 나중에 복합 클래스가 될 경우를 대비하여 C ++에서 접두어 증가 연산자를 사용해야합니다 .이 경우 불필요하게 임시 오브젝트를 작성해야합니다. 나는 postfix 연산자가 미적으로 기쁘게 생각합니다.
mc0e

2
나는 한 줄 버전을 선호합니다. 스택 작업을 생각 나게합니다. push는 array [++ i] = foo이고 pop은 bar = array [i--]입니다. (그러나 0 기반 배열의 경우 array [i ++] = foo 및 bar = array [-i]가 여전히 더 좋습니다.) 또 다른 것은 누군가 누군가 i ++ 사이에 여분의 코드를 추가하면 싫어할 것입니다. 그리고 array [i] = foo ;.
Florian F

257

나는 그 조언에 솔직히 혼란스러워합니다. 저의 일부는 자바 스크립트 코더에 대한 경험 부족 (인지 또는 실제)과 더 관련이 있는지 궁금합니다.

누군가가 일부 샘플 코드에서 "해킹"하는 방법이 ++와 무고한 실수를 할 수있는 방법을 알 수 있지만 숙련 된 전문가가 왜 피할 수 없는지 알 수 없습니다.


7
좋은 지적 Jon B. 그것이 저를 귀찮게하는 이유입니다. Crockford는 경력 프로그래머 (수십 년)이며 수십 년 동안 여러 언어를 사용하며, 처음부터 JavaScript를 사용하여 작업합니다. 그의 조언은 "저는 게으르고 부주의 한 경험이없는 해커입니다"라고 생각하지 않습니다. 그것이 내가 어디에서 왔는지 이해하려고하는 이유입니다.
artlung 2016 년

14
@artlung 어쩌면 "게으르고 부주의 한 경험이없는 해커"와 더 관련이있을 수 있습니다.
Chris Cudmore

9
나는 당신의 대답에 전적으로 동의하지 않습니다. 제 생각에는 '사용하기에 충분한 경험이 있습니까?'가 아닙니다. -그러나 '더 명확합니까?' for 루프 안에 있거나 홀로 있다면, 그것은 분명합니다. 모두가 해를 끼치 지 않고 그것을 이해할 것입니다. ++++ x에서 더 복잡한 표현을 할 때 문제는 x + +와 다르므로 읽기가 쉽지 않습니다. Crockford 아이디어는 '할 수 있습니까?'가 아닙니다. '오류를 피하는 방법'에 관한 것입니다.
ArtoAle

1
간결함보다 선명함이 더 중요한 시점에서 개인 취향입니다. 이것은 코드를 이해하기에 충분한 경험을 넘어선 것입니다. 가치보다 문제가 많은 예는 다른 답변을 참조하십시오.
Frug

1
전적으로 동의합니다. 왜 언어의 일부를 사용하지 않아서 장애가 있습니까? 포스트 증분과 프리 증분과 감소를 모두 사용해야하는 이유를 찾았습니다. 나에게, 이와 같은 줄은 명확하고 간결합니다 ... if (--imagesLoading === 0) start (); 코드가 명확하지 않다고 생각되면 주석을 사용하십시오!
xtempore

69

C에는 다음과 같은 일을 한 역사가 있습니다.

while (*a++ = *b++);

문자열을 복사하려면 아마도 이것이 언급 한 과도한 속임수의 원천 일 것입니다.

그리고 항상 무엇에 대한 질문이 있습니다

++i = i++;

또는

i = i++ + ++i;

실제로 그렇습니다. 일부 언어로 정의되어 있으며 다른 언어에서는 어떤 일이 일어날 지 보장하지 않습니다.

이러한 예를 제외하고는 ++증가 하는 데 사용하는 for 루프보다 관용적 인 것이 없다고 생각 합니다. 어떤 경우에는 foreach 루프 또는 다른 조건을 확인한 while 루프를 사용하여 벗어날 수 있습니다. 그러나 증분을 사용하지 않고 코드를 왜곡하는 것은 어리 석습니다.


104
i = i ++ + ++ i; 내 눈을 조금 아프게했다-:)
Hugoware

3
내 것도. 그것들이 모두 같은 변수가 아니더라도, x = a ++ + ++ b; 그 조합은 즉시 x, a 및 b를 머리에 붙잡기 어렵게 만듭니다. 이제, 각각이 별도의 줄에 별도의 문장이라면-a ++; ++ b; x = a + b; 첫눈에 이해하는 것이 더 쉬울 것입니다.
artlung

10
아아, (a ++; b ++; x = a = b)는 (a ++ + ++ b)와 같은 값이 아닙니다.
토마스 엘 할러데이

8
@ 마리우스 : x = a+++b-> x = (a++)+b-> x = a + b; a++. 토큰 라이저는 탐욕 스럽습니다.
Callum Rogers

14
추가 작업 안전을 위해 마지막 예에서 공백을 제거하십시오.
mc0e

48

JavaScript The Good Parts를 읽으면 for 루프 에서 Crockford의 i ++ 대체 가 i + = 1 (i = i + 1 아님) 임을 알 수 있습니다 . 그것은 꽤 깨끗하고 읽을 수 있으며 무언가 까다로운 것으로 변형 될 가능성이 적습니다.

크록 포드는 자동 증가를 허용하지하고 자동 감소 만든 옵션 jsLint에 있습니다. 조언을 따를 지 여부를 선택합니다.

내 자신의 개인 규칙은 자동 증가 또는 자동 감소와 결합 된 것을하지 않는 것입니다.

수년간의 C 경험을 통해 간단한 사용으로 버퍼 오버런 (또는 배열 인덱스가 범위를 벗어남)을 얻지 못한다는 것을 배웠습니다. 그러나 같은 문장에서 다른 일을하는 "과도하게 까다로운"관행에 빠지면 버퍼 오버런이 발생한다는 것을 알게되었습니다.

따라서 내 규칙에 대해서는 for 루프 에서 i ++를 증분으로 사용하는 것이 좋습니다.


"plusplus"옵션에 대한 훌륭한 점은 바로 그 옵션입니다. 당신과 다른 대답을 바탕으로 ++ 자체 또는 for 루프가 혼란스럽지 않다는 느낌이 들었습니다. 두 번째로 그 ++을 다른 명령문으로 결합하면 문맥에서 읽고 이해하기가 더 어려워집니다.
artlung 2016 년

6
모두 버퍼 오버플로가 발생합니다. 공개 소스와 여러 개정판을 포함한 OpenSSH조차
Eric

11
@Eric 5 살짜리 코멘트를 다시 보아라 .
wchargin

27

루프에서는 무해하지만 할당 문에서 예기치 않은 결과가 발생할 수 있습니다.

var x = 5;
var y = x++; // y is now 5 and x is 6
var z = ++x; // z is now 7 and x is 7

변수와 연산자 사이의 공백은 예기치 않은 결과를 초래할 수 있습니다.

a = b = c = 1; a ++ ; b -- ; c; console.log('a:', a, 'b:', b, 'c:', c)

클로저에서 예기치 않은 결과도 문제가 될 수 있습니다.

var foobar = function(i){var count = count || i; return function(){return count++;}}

baz = foobar(1);
baz(); //1
baz(); //2


var alphabeta = function(i){var count = count || i; return function(){return ++count;}}

omega = alphabeta(1);
omega(); //2
omega(); //3

그리고 개행 후에 자동 세미콜론 삽입을 트리거합니다.

var foo = 1, bar = 2, baz = 3, alpha = 4, beta = 5, delta = alpha
++beta; //delta is 4, alpha is 4, beta is 6

사전 증분 / 사후 증분 혼동은 진단하기 매우 어려운 개별 오류를 생성 할 수 있습니다. 다행히도, 그들은 또한 불완전합니다. 변수에 1을 더하는 더 좋은 방법이 있습니다.

참고 문헌


13
그러나 연산자를 이해하면 "예기치 않은"것은 아닙니다. 그것은 지금까지 사용하지 않는처럼 ==당신의 차이를 이해하지 않기 때문에 ==그리고 ===.
greg84

1
바로 그거죠. 잘못된 가정을 반박 하는 C # 질문 이 있습니다.
Paul Sweatte

Crockford의 요점은 대부분의 프로그래머가 생각하는 경우에도 "운영자를 완전히 이해하지 못한다"는 것입니다. 따라서 오해의 가능성이 높기 때문에 사용에 위험이 있습니다. 사람들이 일반적으로 접두사와 접미사 연산자가 실제로 어떻게 작동하는지 오해한다는 주장을 뒷받침하는 잘못된 가정에 대한 @Paul의 의견을 참조하십시오. 즉, 나는 그것들을 사용하는 것을 좋아하지만 다른 사람들을 위해 관용적 인 경우로 사용을 제한하려고합니다 ( cdmckay의 답변 참조 ).
gfullam

공백 링크가 끊어진 것 같습니다.
Ruslan

"공백"예제에서 까다로운 점은 무엇입니까? 의 간단한 출력을 얻습니다 a: 2 b: 0 c: 1. 첫 번째 예제 ( "할당 진술")에서도 이상하거나 예상치 못한 것을 보지 못했습니다.
Ken Williams

17

다음 코드를 고려하십시오

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[i++] = i++;
    a[i++] = i++;
    a[i++] = i++;

i ++은 두 배로 평가되므로 출력은 (vs2005 디버거에서)

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

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

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = ++i;
    a[++i] = ++i;
    a[++i] = ++i;

출력은 동일합니다. 이제 ++ i와 i ++가 같다고 생각할 수도 있습니다. 그들은 아닙니다

    [0] 0   int
    [1] 0   int
    [2] 2   int
    [3] 0   int
    [4] 4   int

마지막 으로이 코드를 고려하십시오

    int a[10];
    a[0] = 0;
    a[1] = 0;
    a[2] = 0;
    a[3] = 0;
    int i = 0;
    a[++i] = i++;
    a[++i] = i++;
    a[++i] = i++;

결과는 다음과 같습니다.

    [0] 0   int
    [1] 1   int
    [2] 0   int
    [3] 3   int
    [4] 0   int
    [5] 5   int

그래서 그것들은 동일하지 않으며, 두 가지를 혼합하면 그렇게 직관적 인 행동을하지 않습니다. 나는 for 루프가 ++에서는 괜찮다고 생각하지만 같은 줄이나 동일한 명령어에 여러 ++ 기호가있을 때 조심하십시오.


3
실험 해 주셔서 감사합니다. 특히 "단순하게 보이는"코드이지만 뇌가 매우 빨리 붙잡기가 어렵습니다. "까다로운"범주에 속합니다.
artlung 2016 년

28
첫 번째 예제 후에 멈췄습니다. "다음 코드를 고려하십시오"라고 말했습니다. 아니요, 아무도 그 코드를 작성하지 않습니다. 언어 구성이 아니라 결함이있는 사람을 쓴 사람은 바보입니다.
Sam Harwell

4
두 개의 서로 다른 코드 조각이 다른 출력을 생성한다는 것을 보여주었습니다.
nickf

7
결론은 "같은 줄이나 같은 명령어에 여러 개의 ++ 기호가있을 때주의하십시오"입니다. 난 당신이 그것을 읽은 것 같아요
에릭

1
"i ++가 두 번 평가되므로"-잘못된 것입니다! 시퀀스 포인트 사이에서 변수를 두 번 수정하고 사용하는 것은 C ++에서 유효하지 않으며 정의되지 않은 동작으로 이어집니다. 따라서 컴파일러는 원하는대로 할 수 있습니다. 여기에 제시된 결과는 우연히 컴파일러 구현으로 인한 것입니다.
tbleher

16

증가 및 감소 연산자의 "사전"및 "사후"특성은 익숙하지 않은 사용자에게는 혼동을 줄 수 있습니다. 그것이 까다로울 수있는 한 가지 방법입니다.


29
합의 그러나 숙련 된 전문가 혼동해서는 안됩니다.
Nate

1
나는 이것이 모든 것을 정적으로 만들거나 전역 적으로 만드는 것을 피하기위한 지침과 비슷하다고 생각합니다. 프로그래밍 구조로는 본질적으로 아무런 문제가 없지만, 과도한 사용으로 인해 코드가 잘못 될 수 있습니다.
Joel Martinez

6
문제는 좋은 프로그래머가 논리를 통해 "자신의 방식으로 작업"할 수 있는지 여부가 아닙니다. 좋은 코드는 이상적으로 이해해야 할 작업이 필요하지 않습니다. McWafflestix의 요점은 간단한 검사시 2 주 또는 2 년 내에 버그를 추가 할 수있는 코드를 작성해서는 안된다는 것입니다. 나는 내가 완전히 이해하지 못하는 루틴에 코드를 추가하는 것이 유죄임을 알고있다 :)
Mike

1
@ Mike : yah, 운영자가 코드의 원래 작성자 또는 나중에 유지 보수 담당자에게 까다로울 수 있는지 여부를 지정하지 않은 방법에 주목하십시오. 일반적으로, 우리는 원래의 코더들이 익숙하지 않거나 익숙하지 않은 구조를 사용하지 않는다고 가정합니다 (슬프게도 이것은 종종 잘못된 가정입니다). 그러나 친숙 함은 확실히 관리자에게까지 확장되지 않으며 (위에서 괄호로 언급했듯이 orignal author까지 확장되지 않을 수도 있음).
Paul Sonier

다른 프로그래머가 읽을 수 있도록 코드를 작성하려고하지만 초보자가 읽을 수 있도록 코드 를 작성하려고 하지는 않습니다 .
Luke H

16

내 견해로는 "명시 성이 항상 암시 적보다 낫다" 어느 시점에서이 increments 문과 혼동 될 수 있습니다 y+ = x++ + ++y. 좋은 프로그래머는 항상 자신의 코드를 더 읽기 쉽게 만듭니다.


1
x ++ 또는 ++ y에는 암시적인 것이 없습니다.
Florian F

1
읽을 수있는 코드 는 까다 롭습니다 ... 코드가 얼마나 단순해야하는지에 대한 기준선이 있다고 생각합니다. 커뮤니티로서 우리는 조금 번창하고 지금 읽을 수없는 것을 읽을 수 있어야합니다. 더 많은 것들을 시작하도록 중첩 된 삼항으로.
Hamza Ouaghad

14

++ 또는-를 피하기위한 가장 중요한 근거는 연산자가 값을 반환하고 동시에 부작용을 일으켜 코드에 대한 추론을 어렵게한다는 것입니다.

효율성을 위해 다음을 선호합니다.

  • ++ i 반환 값을 사용하지 않을 때 (임시 없음)
  • 반환 값을 사용할i ++ (파이프 라인 중단 없음)

저는 Crockford 씨의 팬이지만이 경우에는 동의하지 않습니다. ++i구문 분석 할 텍스트가 25 % 적 i+=1 으며 분명히 더 명확합니다.


13

나는 이것에 대해 Douglas Crockford의 비디오를보고 있었고 증가와 감소를 사용하지 않는 것에 대한 그의 설명은

  1. 과거에는 다른 언어로 배열의 경계를 허물고 모든 방식의 나쁨과
  2. 더 혼란스럽고 경험이 부족한 JS 개발자는 정확히 무엇을 알지 못합니다.

첫째로 JavaScript의 배열은 동적으로 크기가 조정되므로 잘못하면 용서하십시오. 배열의 경계를 깨고 JavaScript 에서이 메소드를 사용하여 액세스해서는 안되는 데이터에 액세스 할 수 없습니다.

둘째, 복잡한 것을 피해야합니다. 문제는이 기능이 없다는 것이 아니라 문제는 JavaScript를 요구하는 개발자가 있지만 이러한 연산자의 작동 방식을 모른다는 것입니다. 충분히 간단합니다. value ++, 현재 값을 지정하고 표현식 뒤에 ++ value를 추가하고 값을 제공하기 전에 값을 증가시킵니다.

++ + ++ b와 같은 표현식은 위의 내용 만 기억하면 해결하기 쉽습니다.

var a = 1, b = 1, c;
c = a ++ + ++ b;
// c = 1 + 2 = 3; 
// a = 2 (equals two after the expression is finished);
// b = 2;

JS를 알고있는 팀이 있다면 걱정할 필요가 없습니다. 코드를 읽는 사람을 기억해야한다고 생각합니다. 그렇지 않은 경우 의견을 말하고 다르게 작성하십시오.해야 할 일을하십시오. 나는 증가와 감소가 본질적으로 나쁘거나 버그 생성 또는 취약점 생성이라고 생각하지 않습니다.

Btw, 나는 Douglas Crockford가 어쨌든 전설이라고 생각하지만, 그는 가치가없는 운영자에 대해 많은 두려움을 일으켰습니다.

그래도 틀린 것으로 판명되었습니다 ...


10

또 다른 예는 증분 값의 간단한 반환으로 다른 것보다 더 간단합니다.

function testIncrement1(x) {
    return x++;
}

function testIncrement2(x) {
    return ++x;
}

function testIncrement3(x) {
    return x += 1;
}

console.log(testIncrement1(0)); // 0
console.log(testIncrement2(0)); // 1
console.log(testIncrement3(0)); // 1

보시다시피,이 연산자가 결과에 영향을 미치기를 원하는 경우, return 문에서 증가 후 / 감소를 사용해서는 안됩니다. 그러나 리턴은 후행 증가 / 감소 연산자를 "잡지"않습니다.

function closureIncrementTest() {
    var x = 0;

    function postIncrementX() {
        return x++;
    }

    var y = postIncrementX();

    console.log(x); // 1
}

함수 중 하나만 x를 매개 변수로받습니다
Calimero100582

8

프로그래머는 사용하는 언어에 능숙해야한다고 생각합니다. 명확하게 사용하십시오. 잘 사용하십시오. 나는 그들이 사용하는 언어를 인위적으로 약화시켜야한다고 생각 하지 않습니다 . 나는 경험에서 말합니다. 나는 한때 말 그대로 코볼 상점 옆에서 일했는데 그들은 너무 복잡해서 ELSE를 사용하지 않았습니다. Reductio ad absurdam.


@downvoter 매혹적인. 프로그래머가 언어에 능숙해야한다고 생각하지 않습니까? 당신은 그들이 언어를 인위적으로 약화 시켜야 한다고 생각 합니까? 무엇 이니? 세번째 선택은 없습니다.
Lorne의 후작

1
그 코볼 예를 들어 upvote에, 나는 코딩에 도착하기 전에 COBOL 대부분 멸종 것을 더욱 기쁜 날 수 있습니다
마크 K 코완을

1
@MarkCowan 왜 그런지 모르겠습니다. 내 요점은 언어가 아닌 임의의 제한에 관한 것입니다. 일화는 Cobol에 어떤 문제도 나타내지 않습니다. 죽어야했던 것은 프로그래밍 가게 였고 그랬습니다. 큰 은행의 창자를 방문하면 Cobol이 살아 있고 잘 있습니다.
Lorne의 후작

2

기존 답변 중 일부에서 언급했듯이 (귀찮게 언급 할 수없는) 문제는 x ++ ++ x가 다른 값으로 평가된다는 것입니다 (증가 전과 비교 후). 명확하지 않고 매우 혼란 스러울 수 있습니다. 해당 값이 사용되는 경우 cdmckay는 증가 연산자를 사용할 수 있도록 현명하게 제안하지만 리턴 된 값이 사용되지 않는 방식 (예 : 자체 행)입니다. 또한 for 루프 내에 표준 사용을 포함시킬 것입니다 (그러나 반환 값이 사용되지 않는 세 번째 문에서만). 다른 예를 생각할 수 없습니다. 나 자신을 "번트"했으므로 다른 언어에도 같은 지침을 권장합니다.

이 과도 엄격함은 많은 JS 프로그래머가 경험이 없기 때문에 발생한다는 주장에 동의하지 않습니다. 이것은 "과도한"프로그래머의 전형적인 글쓰기의 정확한 종류이며, 더 전통적인 언어와 그러한 언어의 배경을 가진 JS 개발자에게 훨씬 더 일반적이라고 확신합니다.


1
답장을 보내 주셔서 감사합니다. 댓글을 달려면 평판 값이 50 이상이어야합니다. 참조 : stackoverflow.com/faq
artlung

1
@ artlung : 나는 그것을 알고 있으며 그 이유는 알고 있습니다. 방금 짜증나게 말하고 있었어요 :)
Privman 근처

2

내 경험상, ++ i 또는 i ++는 연산자의 작동 방식에 대해 처음 배우는 것 외에 다른 혼란을 일으키지 않았습니다. 가장 기본적인 for 루프와 while 루프는 운영자를 사용할 수있는 언어로 가르치는 고등학교 또는 대학 과정에서 가르치는 것입니다. 개인적으로 ++가 별도의 줄에있는 것보다 더 잘 보이고 읽기 위해 아래의 것과 같은 것을하는 것을 발견했습니다.

while ( a < 10 ){
    array[a++] = val
}

결국 그것은 스타일 선호이며 더 이상은 아닙니다. 더 중요한 것은 코드 에서이 작업을 수행 할 때 일관성을 유지하여 동일한 코드로 작업하는 다른 사람들이 다른 방식으로 동일한 기능을 수행하고 처리 할 필요가 없도록하는 것입니다 .

또한 Crockford는 i- = 1을 사용하는 것 같습니다. i- = 1보다 더 읽기 어렵습니다.


2

내 2 센트는 두 가지 경우에 피해야한다는 것입니다.

1) 많은 행에서 사용되는 변수가 있고 변수를 사용하는 첫 번째 명령문에서 변수를 증가 / 감소시키는 경우

// It's Java, but applies to Js too
vi = list.get ( ++i );
vi1 = list.get ( i + 1 )
out.println ( "Processing values: " + vi + ", " + vi1 )
if ( i < list.size () - 1 ) ...

이와 같은 예제에서 변수가 자동 증가 / 감소되거나 첫 번째 명령문을 제거하는 것을 쉽게 놓칠 수 있습니다. 즉, 매우 짧은 블록에서만 또는 변수가 블록에서 두 개의 가까운 명령문에서만 나타나는 위치에서만 사용하십시오.

2) 여러 ++ 및-의 경우 동일한 명령문에서 동일한 변수에 대해. 다음과 같은 경우에 어떤 일이 발생하는지 기억하기가 매우 어렵습니다.

result = ( ++x - --x ) * x++;

시험과 전문 테스트는 위와 같은 예제를 요구하며 실제로 그중 하나에 대한 문서를 찾는 동안이 질문에 걸려 들었지만 실제로는 한 줄의 코드에 대해 그렇게 많이 생각해서는 안됩니다.


1

포트란은 C와 같은 언어입니까? ++도없고-도 없습니다. 다음은 루프를 작성하는 방법입니다 .

     integer i, n, sum

      sum = 0
      do 10 i = 1, n
         sum = sum + i
         write(*,*) 'i =', i
         write(*,*) 'sum =', sum
  10  continue

루프를 통해 매번 언어 규칙에 따라 인덱스 요소 i 가 증가합니다. 예를 들어 1이 아닌 다른 값으로 늘리려면 2를 거꾸로 세십시오. 구문은 다음과 같습니다.

      integer i

      do 20 i = 10, 1, -2
         write(*,*) 'i =', i
  20  continue

파이썬 C와 비슷합니까? 그것은 사용 범위목록 함축 하고 인덱스를 증가의 필요성 우회 다른 구문을 :

print range(10,1,-2) # prints [10,8.6.4.2]
[x*x for x in range(1,10)] # returns [1,4,9,16 ... ]

따라서 정확히 두 가지 대안에 대한 기초적인 탐구를 바탕으로 언어 디자이너는 ++를 피하고 사용 사례를 예상하고 대체 구문을 제공함으로써 ++를 피할 수 있습니다.

Fortran과 Python은 ++와-를 가진 절차 적 언어보다 버그 자석이 적습니까? 증거가 없습니다.

나는 Fortran과 Python이 C와 비슷하다고 주장합니다 .C에 유창한 사람을 만나지 못했기 때문에 90 %의 정확도로 난독 화되지 않은 Fortran 또는 Python의 의도를 정확하게 추측 할 수 없습니다.


1
예, IFortran은 1950 년대에 왔고 C는 1970 년대에 있었으므로 Fortran은 C와 같지 않습니다. plusplus 연산자와 같은 것이 부족한 Python의 예가 흥미 롭습니다. 데이터 구조에 대한 반복은 파이썬에서보다 명확하게 처리되며, 파이썬은 "다른"객체 지향 JavaScript입니다. 아마도 Crockford의 조언은 반복에 더 많은 OO와 유사한 구문을 사용하는 것에 관한 것입니다.
artlung
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.