초등학교 때부터 수학을 배우면서 다양한 연산자를 접할 수 있었음. 연산자에는 더하기(+), 빼기(-), 곱하기(*) 등과 같은 것들이 있음.
이번 포스팅에서는 학교 수학시간에 다루지 않았던 연산자의 면에 집중해서 해볼 예정.
용어 : "unary(단항)", "binary(이항)", "operand(피연산자)"
일단 연산자에 들어가기 전에 용어에 대해 정의를 하고 넘어갈 예정.
◉ operand(피연산자) : 피연산자는 연산을 하는 대상을 의미함. 예를 들어 5 * 2 와 같은 연산을 할 때, 2개의 피연산자가 존재함. 이 연산에서 왼쪽 피연산자는 5가 될 것이고 오른쪽 피연산자는 2가 될 것임. 가끔 사람들은 피연산자 대신에 argument라고 부름
◉ 연산이 unary(단항)이라는 의미는 피연산자가 하나일 때를 의미함. 예를들어 음수를 표시하는 - 가 대표적인 예임.
1 2 3 4 5 | let x = 1; x = -x; alert(x); // -1, unary negation was applied | cs |
◉ 연산이 binary(이항)이라는 의미는 피연산자가 두 개라는 의미. 이항에서의 - 는 두 피연산자를 뻬는 역할을 수행함.
1 2 3 4 | let x = 1; let y = 3; alert(y - x); //2, binary minus subtracts values | cs |
1 2 | let s = "my" + "string"; alert(s); // mystring | cs |
1 2 | alert("1" + 2); // "12" alert(2 + "1"); // "21" | cs |
1 | alert(2 + 2 + '1'); // "41", not "221" | cs |
1 2 | alert(2 - '1'); // 1 alert('6' / '2'); // 3 | cs |
더하기(+)는 두 가지 형태로 존재함. 첫 번째로, 위에서 언급했던 이항 연산 + , 두 번째로, 단항 연산의 형태가 있음.
즉, 단항 연산 +는 더하기 연산 +를 하나의 값에 적용시키고 숫자로 어떠한 연산을 하지 않을 때 적용됨. 그러나 피연산자가 숫자가 아닐 때, 단항 연산 +는 값을 숫자로 바꾸어 버림.
1 2 3 4 5 6 7 8 9 10 | //No effect on numbers let x = 1; alert(+x); //1 let y = -2; alert(+y); // -2 //Converts non-numbers into a number alert(+true); // 1 alert(+""); // 0 | cs |
위의 예를 보면 Number(..) 함수로 형변환하는 역할과 비슷한 역할을 함. 단지 Number(..) 함수보다 더 짧게 쓰는 차이만 있음.
종종 String을 숫자로 바꾸어야 하는 경우가 있음. 예를 들어 HTML의 form 필드에서 값을 가져올 때, 그 값들이 대부분 String타입임.
만약 얘네를 더하기 연산을 하면 위에서 언급한 바와 같이 String타입이기 때문에 값이 더해지지 않고 연결됨.
1 2 3 4 | let apples = '2'; let oranges = '3'; alert(apples + oranges); // 23 | cs |
1 2 3 4 | let apples = '2'; let oranges = '3'; alert(+apples + +oranges); // 5 | cs |
위에 예시를 수학자의 관점에서 본다면 + 기호를 매우 많이 써서 이상해보일지 모름. 그러나 프로그래머 관점에서 보면 이상할 것이 없는 코드임! 단항의 + 가 먼저 적용되어 변수나 값을 String타입에서 number타입으로 형변환을 해주고 그 다음 이항 연산의 덧셈(+)을 해줌!
연산의 우선순위
만약 코드에서 하나 이상의 연산을 한다면 실행의 순서는 연산의 우선순위에 의해 결정됨. 즉, 연산자의 보이지 않는 우선순위가 있다는 말!
학교에서는 1 + 2 * 2가 있다면 곱셈을 먼저한 다음 덧셈을 하라는 방식으로 배움. 이게 바로 연산의 우선순위임! 곱셈은 덧셈보다 연산 우선순위가 높다고 할 수 있음.
어떠한 연산을 둘러싸고 있는 괄호는 이런 연산의 우선순위를 무시하고 먼저 계산됨, 따라서 1 + 2 * 2와 (1 + 2) * 2의 계산의 값은 달라지게 됨.
자바스크립트에는 다양한 연산자가 존재하며 각 연산자는 우선순위가 부여되어 있기 때문에 우선순위가 높은 연산은 먼저 실행됨. 만약 우선 순위가 같은 레벨이라면 실행의 순서는 왼쪽에서 부터 오른쪽으로 가는 것이 일반적임.
아래는 기억할만한 우선순위 테이블임.
Precedence | Name | Sign |
---|---|---|
… | … | … |
16 | unary plus | + |
16 | unary negation | - |
14 | multiplication | * |
14 | division | / |
13 | addition | + |
13 | subtraction | - |
… | … | … |
3 | assignment | = |
… | … | … |
위에 보는 바와 같이 단항 플러스의 우선순위는 16이고, 이항 연산의 덧셈은 13임. 따라서 "+apples + +orages"의 식에서 단항 플러스가 먼저 실행되게 됨!
Assignment(대입)
대입 연산(=)도 연산자의 종류 중 하나임. 우선 순위 테이블에서 보면 대입연산의 우선순위는 3으로 매우 낮은 쪽에 속해 있음.
그래서 x = 2 * 2 + 1과 같은 연산을 할 때 뒤의 계산이 다 된 후, x라는 변수에 결과 값이 대입됨.
1 2 3 | let x = 2 * 2 + 1; alert(x); // 5 | cs |
대입은 여러 변수를 한번에 체인 처럼 연결하여 대입 연산도 가능함.
1 2 3 4 5 6 7 | let a, b, c; a = b = c = 2 + 2; alert(a); // 4 alert(b); // 4 alert(c); // 4 | cs |
체인 대입은 오른쪽에서 왼쪽으로 실행됨. 첫 번째로 가장 오른쪽에 있는 표현식인 2 + 2는 먼저 값인 4가 계산되고 그 결과 값이 c, b, a 순으로 대입됨.
# 대입 연산 '='는 값을 리턴함.
연산자는 항상 값을 리턴하게 되어있음. 이는 덧셈이나 곱셈이 값을 연산해서 결과의 값을 리턴해줌! 이 규칙은 대입연산에서도 적용됨.
x = value라는 함수는 쓴다고 가정하면 value는 변수 x에 담겨서 그 값을 리턴함.
1 2 3 4 5 6 7 | let a = 1; let b = 2; let c = 3 - (a = b + 1); alert(a); // 3 alert(c); // 0 | cs |
나머지 연산 %
나머지 연산인 %는 보이는 것처럼 퍼센트 연산과 관련있지는 않음..!
a % b의 결과는 a를 b로 나누었을 때의 나머지 정수를 반환함.
1 2 3 | alert(5 % 2); // 1 alert(8 % 3); // 2 alert(6 % 3); // 0 | cs |
지수 연산 **
지수 연산 **는 최근에 자바스크립트에 추가된 연산자임.
a ** b의 결과는 지수 계산처럼 a라는 값을 b번 곱하는 결과가 나타남.
1 2 3 | alert(2 ** 2); // 4 (2 * 2) alert(2 ** 3); // 8 (2 * 2 * 2) alert(2 ** 4); // 16 (2 * 2 * 2 * 2) | cs |
1 2 | alert( 4 ** (1/2) ); // 2 (same as square root (제곱근)) alert( 8 ** (1/3) ); // 2 (same as cubic root(세제곱근)) | cs |
숫자가 1씩 증가하거나 감소하는 것은 매우 흔한일임. 그래서 자바스크립트에는 이런 연산을 위한 특별한 연산자가 있음!
- 1 증가 연산 : ++
1 2 3 | let counter = 2; counter++; alert(counter); // 3 | cs |
- 1 감소 연산 : --
1 2 3 | let counter = 2; counter--; alert(counter); // 1 | cs |
증가/감소 연산인 ++와 --는 변수의 앞이나 뒤에 붙을 수 있음.
- 연산자가 변수 뒤에 오는 경우 "후치 형태(postfix form)"이라고 부름 ex) counter++
- 연산자가 변수 앞에 오는 경우 "전치 형태(prefix form)"이라고 부름 ex) ++counter
두 형태 모두 counter라는 변수의 값을 1 증가 시키는 역할을 하는 것은 동일함.
그렇다면 두 형태의 차이는 무엇일까? 앞서 언급한 바와 같이 모든 연산자는 값을 리턴함. 증가/감소 연산도 예외가 아님. 후치 형태와 전치 형태의 차이는 후치 형태(postfix form)은 증가/감소 이전의 값을 리턴하는 반면에 전치 형태(prefix form)은 증가/감소 이후의 값을 리턴함.
아래의 예제를 보자!
1 2 3 4 5 6 7 8 9 10 11 12 13 | let counter = 1; let a = ++counter; alert(a); // 2 //////////////////// let counter = 1; let a = counter++; alert(a); // 1 | cs |
# 다른 연산자 사이에서의 증가/감소 연산
연산자 ++/--는 다른 연산자가 사용되는 코드 안에서 함께 쓰일 수 있음. 증가/감소 연산은 다른 수학 연산자들보다 우선순위가 높기 때문에 먼저 실행됨.
1 2 | let counter = 1; alert(2 * ++counter); //4 | cs |
1 2 3 | let counter = 1; alert(2 * counter++); //2 alert(counter); //2 | cs |
1 2 3 | let counter = 1; alert(2 * counter); counter++; | cs |
비트 연산자
비트연산자는 32비트의 정수를 다루며 이진 표현의 레벨에서 이루어짐.
이 연산자들은 JavaScript에서만 쓰이는 것이 아니고 대부분의 프로그래밍 언어에서 사용됨.
이 연산자들에는 AND(&), OR(|), XOR(^), NOT(~), LEFT SHIFT(<<), RIGHT SHIFT(>>), ZERO-FILL RIGHT SHIFT(>>>) 가 있음.
이런 연산자들은 거의 사용을 할 일이 없기 때문에 이런 연산자들이 있다는 것만 언급하고 필요하다면 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators 이 사이트를 참조하면 될 듯!
한 위치에서 수정하기
가끔 코드를 짤 때, 한 변수의 값에 추가 연산을 한 다음 같은 변수에 이 결과 값을 저장해야할 때가 있음.
아래와 같은 예시가 그런 경우임!
1 2 3 | let n = 2; n = n + 5; n = n * 2; | cs |
1 2 3 4 | let n = 2; n *= 3 + 5; alert(n); // 16 ( n = 2 * (3 + 5) ) |
콤마( , ) 연산자는 연산자 중에서 가장 사용하지 않는 코드 중 하나임. 가끔 짧은 코드를 작성하기 위해서 사용하기 때문에 이 코드가 어떤 방식으로 동작하는지는 알 필요가 있음.
콤마 연산자는 몇몇 표현을 콤마로 나누어서 판단할 수 있도록함. 콤마로 분리하여 각각 연산을 하지만 결과 값은 결국 마지막만 리턴됨.
1 2 | let a = (1 + 2, 3 + 4); alert(a); // 7 (the result of 3 + 4) | cs |
위의 예시에서 보면 1+2와 3+4의 연산은 각각 이루어 지지만 가장 마지막 값은 7만 메세지에 나타남.
# 콤마는 가장 낮은 우선순위를 갖고 있습니다!
콤마는 할당 연산자(=)보다도 낮은 우선순위를 가지고 있음. 그래서 콤마 연산자를 사용하기 위해서는 괄호로 묶어주는 것이 필요함!
1 2 3 4 | // threee operations in one line for (a = 1, b = 3, c = a * b; a < 10; a++) { .... } | cs |
'자바스크립트' 카테고리의 다른 글
[JavaScript공부 - 10] Interaction(상호작용):alert, prompt. comfirm (0) | 2019.02.11 |
---|---|
[JavaScript공부 - 9] Comparisons(비교) (0) | 2019.02.01 |
[JavaScript공부 - 7] Type Conversions(타입 변환) (0) | 2019.01.25 |
[JavaScript공부 - 6] Data types(데이터 타입) (0) | 2019.01.24 |
[JavaScript공부 - 5] Variables(변수) (0) | 2019.01.21 |
댓글