[Javascript] 5강 표현식과 연산자

 

1. 연산자

JavasScript의 연산자는 다음과 같은 유형으로 나눌 수 있습니다.

  • 할당 연산자
  • 비교 연산자
  • 산술 연산자
  • 비트 연산자
  • 논리 연산자
  • 문자열 연산자
  • 조건(삼항) 연산자
  • 쉼표 연산자
  • 단항 연산자
  • 관계 연산자

JavaScript는 이항 연산자와 단항 연산자 모두를 포함하며, 유일한 삼항 연산자로 조건 연산자도 가지고 있습니다.

피연산자1 연산자 피연산자2

 

이항 연산자의 예시로 3+4와 x*y가 있습니다. 단항 연산자는 연산자의 앞이나 뒤에 하나의 피연산자가 필요합니다.

연산자 피연산자
피연산자 연산자

 

단항 연산자의 예시로 x++ 또는 ++x가 있습니다.

 

2.속성 할당

어떤 표현식이 객체로 평가된다면, 할당 표현식의 좌항은 객체로 평가되는 표현식의 속성에 할당할 수 있습니다.

let obj = {};

obj.x = 5;
console.log(obj.x); // 5 출력
console.log(obj); // { x : 5 } 출력


const key = "y";
obj[key] = 10;
console.log(obj[key]); // 5 출력
console.log(obj); // { x:5, y: 10}

 

어떤 표현식이 객체로 평가되지 않으면, 그 표현식이 속성에 대한 할당 표현식은 실제로 할당하지 않습니다.

let val = 0;

console.log((val.x = 3)); // 3 출력
console.log(val.x); // undefined 출력
console.log(val); // 0 출력.

 

수정 불가능 속성이나, 속성이 없는 표현식(null or undefined)으로 할당 시도시 오류가 발생합니다.

 

3. 구조 분해

구조 분해 할당 구문은 JavaScript 표현식 중 하나로, 객체나 배열을 생성할 때와 비슷한 구문으로 사용해 어떤 객체나 배열에서 데이터를 추출할 수 있습니다.

var foo = ["one", "two", "three"];

// 구조 분해 없음
var one = foo[0];
var two = foo[1];
var three = foo[2];

// 구조 분해 사용
var [one, two, three] = foo;

console.log(foo);

var genre = ["Action", "Adventures", "Thriller"];

var act = genre[0];
var adv = genre[1];
var thr = genre[2];

var [act, adv, thr] = genre;

console.log(genre);

 

4.반환 값과 체이닝

일반적으로, 할당 표현식은 변수 선언(const, let, var)과 함께 쓰거나 독립적인 명령문으로 사용됩니다.

// 변수 x를 선언 f() 결과로 초기화
//  x = f() 할당 표현식의 결과는 버려짐
let x = f();

// 변수 x를 선언해 g()의 결과로 초기화
// x = g() 할당 표현식의 결과는 버려짐
x = g(); // 변수 x를 g()의 결과로 재할당

 

다른 표현식들처럼 x = f()와 같은 할당 표현식도 결과 값으로 평가됩니다. 보통 이 값을 사용하지 않지만, 그래도 다른 평가식의 값으로 사용할 수 있다는 점은 바뀌지 않습니다. 할당 체이닝이나, 다른 표현식에 중첩된 할당은 예상하기 힘든 동작을 보일 수 있습니다.

let x;
const y = (x = f()); // 또는 const  y = x = f();
console.log(y); // x = f() 할당의 반환 값

console.log((x = f())); // 반환 값 직접기록

// 할당 표현식은 보통 표현식을 기대하는 곳이라면 이디에나 중첨 사용 가능
// 배열 리터럴의 요소나 함수의 매개변수도 그런 곳 중 일부임.
console.log([0, (x = f()), 0]);
console.log(f(0, (x = f()), 0));

 

평과 결과는 위쪽 표의 "뜻"열에서 = 기호의 우항 표현식의 결과와 같습니다

function a() {
    console.log("A!");
    return 2;
    
}

function f() {
    console.log("F!");
    return 3;
}

let x, y;
y = x = f();
y = [f(), (x = g())];
x[f()] = g();

 

=는 우측 결합을 하기 때문에 y = x = f()y = (x = f())와 같습니다. 하지만 평가는 오른쪽으로 나아가므로

  1. 할당 표현식 y = x = f()의 평가를 시작.
    1. 이 할당의 좌항인 y가, y라는 이름의 변수 참조로 평가.
    2. 할당 표현식 x = f()의 평가를 시작.
      1. 이 할당의 좌항인 x가, x라는 이름의 변수 참조로 평가
      2. 함수 호출 f()가 콘솔에 "F!"를 기록한 후  숫자 2로 평가
      3. f()의 결과인 2x에 할당합니다.
    3. 할당 표현식 x = f()의 평가 종료. 표현식의 결과 값은 x의 새로운 값, 즉 2
    4. 위의 결과인 2y에도 할당
  2. 할당 표현식 y = x = f()의 평가가 끝났습니다. 표현식의 결과 값은 y의 새로운 값, 즉 2임. xy2를 할당 콘솔에는 "F!" 기록함

5.할당 체이닝을 피해야 할 이유

할당 체이닝이나, 다른 표현식에 중첩된 할당은 예상하기 힘든 동작을 보일 수 있습니다. 특히 const, let, var 명령문에 변수 체인을 사용하면 종종 제대로 동작하지 않고, 가장 바깥(왼쪽) 변수만 선언되며 나머지는 const/let/var이 선언지 않을 것입니다.

let v = (y = x = f());

 

위 명령문을 얼핏 봤을 때  x,y,z 세 변수를 선언하는 모습처럼 보이나 위 코드는 z만 선언합니다. 나머지 y와 x는 엄격모드입니다.

 

6.비교 연산자

 

비교 연산자는 피연산자를 서로 비교하고, 비교 결과가 참인지에 따라 논리 값을 반환하고 피연산자로는 숫자, 문자열, 논리, 객체 값을 사용할 수 있습니다. 문자열은 Unicode 값을 사용한 표준 사전식 순서에 따라 비교합니다.

const var1 = 3;
const var2 = 4;

7. 산술 연산자

산술 연산자는 두 개의 숫자 값(리터럴 또는 변수)을 피연산자로 받아 하나의 숫자 값을 반환합니다. 

1 / 2; // 0.5
1 / 2 == 1.0 / 2.0; //참

 

Javascript는 표준 산술 연산자외에도 아래 표처럼 산술 연산자를 제공합니다.

8. 비트 연산자

비트 연산자는 피연산자를 10진수, 16진수, 8진수 숫자로 취급하지 않고, 대신 32개 비트의 집합으로 취급합니다. 예를 들어 10진수 9는 2진수 1001로 나타냅니다. 비트 연산자는 이러한 이진법 표현에 대해 연산을 수행하지만, 반환일 땐 JavaScript 표준 숫자로 반환합니다.

 

9. 비트 논리 연산자

비트 논리 연산자는 다음과 같이 동작합니다.

  • 두 피연산자를 32비트 정수로 변환해 비트(0 과 1)의 연속으로 표현합니다. 숫자가 32비트를 초과할 경우 가장 큰 비트부터 버립니다. 
전: 1110 0110 1111 1010 0000 0000 0000 0110 0000 0000 0001
후:                1010 0000 0000 0000 0110 0000 0000 0001
  • 왼쪽 피연산자의 각 비트와 오른쪽 피연산자의 각 비트를 순서대로 쌍으로 만듭니다. 즉, 첫 비트는 첫 비트와, 두번째 비트는 두 번째 비트와, ...32번째 비트는 32번째 비트와 짝을 짓습니다.
  • 연산자를 각각의 비트 쌍에 대해 적용한 결과로 비트 단위로 구축합니다.

9의 이진 표현법은 1001로, 15의 이진 표현은 1111입니다. 비트 연산자를 이 두 값에 적용할 때의 결과는 다음과 같습니다.

참고로, 비트 NOT 연산자를 사용하면 32개의 비트를 모두 반전하고, 가장 큰(맨 왼쪽) 비트가 1이면 음수를 나타냅니다.(2의 보수 표현법) ~x-x -1과 같은 값으로 평가됩니다.

 

10. 비트 시프트 연산자

비트 시프트 연산자는 시프트를 적용할 값과, 시프트할 자릿수를 피연산자로 받습니다. 시프트 방향은 사용하는 연산자에 따라 다릅니다. 시프트 연산자는 피연산자를 32비트 정수로 변환하고, 결과 값 Number나 BigInt로 반환합니다. 정확히는,왼쪽 피연산자가 BigInt면 BigInt를 반환하고, 그 외에는 Number를 반환합니다.

11.논리 연산자

논리 연산자는 보통 불리언(논리) 값과 함께 사용해 불리언 값을 반환합니다. 그러나 &&연산자와 || 연산자는 사실 두 피연산자 중 하나늘 반환하는 것으로, 만약 둘 중 하나가 불리언 값이 아니면 논리 연산자의 반환 값도 불리언 값이 아닐 수 있습니다.

 

false로 변환할 수 있는 표현식의 평가 결과가, null, 0 , NaN, 빈 문자열(""), undefined인 경우입니다.

var a1 = true && true; // true 반환
var a2 = true && false; // false 반환
var a3 = false && true; // false반환
var a4 = false && 3 == 4; // false 반환
var a5 = "Red" && "Blue"; // Blue 반환
var a6 = false && "Cat"; // false 반환
var a7 = "Cat" && false; // false 반환
// || 연산자
var b1 = true || false // true 반환
var b2 = false || true; // true
var b3 = true || false; // true 
var b4 = false || 3 == 4; // false 반환
var b5 = "Cat" || "Dog"; // Cat 반환
var b6 = false || "Cat"; // Cat 반환
var b7 = "Cat" || false; // Cat 반환
// ! 연산자
var g1 = !true; // false 반환
var g2 = !false; // true 반환
var g3 = !"Cat"; // false 반환

 

  • false && 아무거나는 거짓으로 단락 평가
  • true || 아무거나는 참으로 평가

논리 규칙은 위 단락 평가가 항상 옮다고 평가하고. 아무거나 부분의 표현식은 평가를 하지 않고, 해당 표현식에 유발하게 되는 부수 효과도 전혀 발생하지 않습니다.

 

12. 문자열 연산자

문자열에 사용할 수 있는 비교 연산자들 외, 문자열 연결( + )연산자는 두 문자열의 값을 서로 연결한 새로운 문자열을 반환합니다.

console.log("Hello" + "String"); // "Hello String" 문자열 기록

 

단축 할당 연산자인 += 또한 문자열을 연결할 때 사용할 수 있습니다.

var mystring = "자바";
mystring += "스크립트"; // "자바스크립트로 평가, mystring에 "자바스크립트" 할당

 

13. 조건 (삼항) 연산자

조건 연산자는 JavaScript에서 세 개의 피연산자를 받는 유일한 연산자로, 조건 연산자는 주어진 조건에 따라 두 값 중 하나를 반환합니다.

condition ? val1 : val2

 

만약 condition이 참이라면, 조건 연산자는 val1을 반환하고, 그 외에는 val2를 반환합니다. 다른 연산자를 사용할 수 있는 곳이라면 조건 연산자도 사용할 수 있습니다. 예를 들어

var status = age >= 19 ? "성인" : "미성년자";

 

위 명령문은 age가 19이상이라면 status에  "성인"을 할당하고, 아니라면 "미성년자"를 할당합니다.

 

14. 쉼표 연산자

쉼표 연산자는 두 피연산자를 모두 평가한 후 오른쪽 피 연산자의 값을 반환합니다. 쉼표 연산자는 주로 for 반복문 안에서 사용해 한 번의 반복으로 여러 변수를 변경할 때 사용합니다. 꼭 필요하지 않다면, 그 외에 상황에 사용하는 것은 좋지 않는 코드 스타일로 여겨집니다. 대개 쉼표 연산자보다 두 개의 분리된 명령문을 사용하는 편이 좋습니다.

 

var x = [0,1,2,3,4,5,6,7,8,9];
var a = [x,x,x,x,x];

// i가 0이고, j는 9 j가 i보다 크거나 같다면 i는 증가하고 j는 감소
for (var i = 0, j = 9; i <= j; i++, j--) {
      console.log("a["+ i + "][" + j + "]= " + a[i][j]);     
}

 

15. 단항 연산자

단항 연산은 오직 하나의 피연산자만 사용하는 연산입니다. 첫번째로 delete 연산자는 객체의 속성을 삭제합니다. 구문은아래와 같습니다.

// 1. 단항 연산자 delete
delete object.prototype;
delete object[propertyKey];
delete objectName[index];

 

위에 부터 objectName은 객체의 이름이고, property는 객체의 존재하는 속성, propertykey는 존재하는 속성을 가리키는 문자열이나 심볼입니다. delete연산자가 속성을 성공적으로 삭제 후, 해당 속성을 접근하려고 하면 undefined를 반환합니다.delete는 속성을 제거할 수 있는 경우 true를 반환하고, 아니면 false를 반환합니다.

delete Math.PI; // false 

const myObj = { h: 5 };
delete myObj.h; // true

 

typeof

 

typeof 연산자는 다음과 같이 사용합니다.

// 2. typeof 
typeof operand;
typeof (operand);

 

typeof 연산자는 평가 전 피연산자 타입을 나타내는 문자열을 반환하고 operand는 문자열, 변수, 키워드, 객체 등 타입을 알아낼 값입니다.

 

typeof operand;
typeof (operand);

var Funs = new Function("3+1");
var shape = "round";
var size = 44;
var foo = ["Apple", "Mongo", "DB"];
var today = new Date();
typeof myFun; // "function" 반환
typeof shape; // "string" 반환
typeof size; // "number" 반환
typeof foo; // "object" 반환
typeof today; // "object" 반환
typeof dontExist; // "undefined" 반환
typeof true; // "boolean" 반환
typeof null; // "object" 반환
typeof 62; // "number" 반환
typeof "Hello world"; // "string" 반환
typeof document.lastModified; // "string" 반환
typeof window.length; // "number" 반환
typeof Math.LN2; // "number" 반환
typeof blur; // "function" 반환
typeof eval; // "function" 반환
typeof parseInt; // "function" 반환
typeof shape.split; // "function" 반환
typeof Date; // "function" 반환
typeof Function; // "function" 반환
typeof Math; // "object" 반환
typeof Option; // "function" 반환
typeof String; // "function" 반환

 

void

 

void 연산자는 다음과 같이 사용합니다.

// 3. void 
void (expressison);
void expressison;

 

void 연산자는 표현식을 평가할 때 값을 반환하지 않도록 지정합니다. expression은 평가할 표현식입니다.

 

16.관계 연산자

관계 연산자는 피연산자를 서로 비교하고, 비교 결과가 참인지에 따라 불리언 값을 반환합니다.

propNameOrNumber in ObjectName;

 

propNameOrNumber는 속성이나 배열 인덱스를 나타내는 문자열, 숫자, 심볼 표현식이며 ObjectName은 객체의 이름입니다. 

var trees = ["rewood", "bay", "cedar", "oak", "maple"];
0 in trees; // true
3 in trees; // true
6 in trees; // false
"bay" in trees; // false no index 
"length" in trees; // true length in array 

// 내장 객체
"PI" in Math; // true 
var myString = new String("coral");
"length" in myString; // true

// 사용자 정의 객체
var mycar = { make: "Honda", model: "Accord", year: 1998 };
"make" in mycar; //true
"model" in mycar; //true

 

17. instanceof

instanceof 연산자는 지정한 객체가 지정한 객체 타입에 속하면 true를 반환합니다.

objectName instanceof objectType;

 

objectName은 objectType와 비교할 객체의 이름이고, objectTypeDate, Array와 같은 객체 타입입니다. 런타임에 객체의 타입을 확인할 필요가 있으면 instanceof 연산자를 사용하세요. 

var theDay = new Date(1939, 9, 1);
if (theDay instanceof Date) {
    console.log("World War II");
    
}

 

18. 연산자 우선 순위

연산자의 우선순위는 표현식을 평가할 때 연산자를 적용하는 순서를 결정합니다. 괄호를 사용하면 우선순위를 바꿀 수 있습니다.

19. 표현식

표현식은 어떤 값으로 이행하는 임의의 유효한 코드 단위이며, 모든 표션식은 구문이 유효하다면 어떤 값으로 이행하지만, 개념적으로 두 가지 범주로 나뉩니다. 하나는 부수 효과가 있는(예: 변수에 값 할당)표현식이고, 다른 하나는 평가하면 어떤 값으로 이행하는 표현식입니다. 

 

x = 10은 앞의 범주가 포함됩니다. 이 표현식은 = 연산자를 사용해 값 7을 x변수에 할당합니다. 표현식 자체도 7로 표현됩니다. 3 + 4는 뒤쪽 범주로 들어갑니다. 이 표현식은 + 연산자를 사용해 3과 4를 더하지만, 결과인 7을 변수에 할당하지 않습니다. 

 

  • 산수: 숫자, 3.14159로 평가됨. 산술 연산자 사용
  • 문자열: 문자열, "ABC", "234"등으로 평가됨, 문자열 연산자를 사용 
  • 논리: 참이나 거짓으로 평가됨, 논리 연산자 포함
  • 일차 표현식: Javascript의 키워드와 일반 표현식
  • 좌변 표현식: 좌변 값은 할당의 목적지

20. 일차 표현식

this 키워드

 

현재 객체를 참조하려면 this키워드를 사용합니다. 일반적으로 this는 메서드의 호출 객체를 참조합니다.

this["propertyName"];
this.propertyName;

 

최대와 최소 값을 받아, 어떤 객체의 value 속성 유효설을 검증하는 validate라는 함수를 만들어줍니다.

function validate(obj, loval, hival) {
    if (obj.value < loval || obj.value > hival) console.log("잘못된 값!");
    
}

 

다음과 같이, 각 양식 요소의 onchange 이벤트 처리기에서 validate 호출할 때 this를 사용해서 양식 요소의 참조를 제공할 수 있습니다.

 

그룹 연산자

 

그룹연산자는 표현식 우선순위를 조절합니다.

// 기본 우선순위
console.log(a + b * c); // 7
console.log(a + (b * c)); // 7

// 순위 재정의
// 곱하기보다 더하기를 먼저 수항
console.log((a + b) * c); // 9
console.log(a * c + b * c); // 9

 

21. 좌변 표현식

 

new 연산자를 사용하면 정의 객체 타입이나 내장 객체 타입의 인스턴스를 생성할 수 있습니다.

var objectNAme = new ObjecType([param1, param2,  , paramN]);

 

super 키워드는 객체의 부모가 가진 함수를 호출할 때 사용합니다.

super([arguments]); // 부모 생성자 호출
super.functionOnParent([arguments]);

 

참고 자료

 

표현식과 연산자 - JavaScript | MDN

이번 장에서는 JavaScript의 표현식과 함께 할당, 비교, 산술, 비트 계산, 논리, 문자열, 삼항 등 다양한 연산자를 살펴보겠습니다.

developer.mozilla.org

 

 

GitHub - javascript-only/javascript-bloging

Contribute to javascript-only/javascript-bloging development by creating an account on GitHub.

github.com

 

LIST