[Day 24] 연산자 더 알아보기 + 브라우저 측 Javascript
연산자 더 알아보기
표현식 (Expression)
- 코드 중에 값으로 변환될 수 있는 부분
- 표현식을 값으로 변환하기 위해 실제로 해당 표현식을 실행시키는 절차를 평가(evaluation) 이라고 한다.
단축 평가 (Short-circuit Evaluation)
-
피연산자가 두 개 이상인 연산 중에, 값을 결정하기 위해 양쪽 피연산자 모두가 필요하지 않은 경우, 모두 연산하지 않고 필요한 연산만 수행한 후 결과값을 return 한다.
false && expression // false true || expression // true // expresion 부분은 연산하지 않는다. (연산할 필요가 없다.)
&&
연산자와||
연산자의 실제 동작 방식&&
- 왼쪽 피연산자를 평가해서 falsy 이면 이 값을 바로 반환한다. 아니면 오른쪽 피연산자를 평가한 결과값을 반환한다.||
- 왼쪽 피연산자를 평가해서 truthy이면 이 값을 바로 반환한다. 아니면 오른쪽 피연산자를 평가한 결과값을 반환한다.
-
단축 평가의 성질을 이용해
if
구문을 흉내낼 수 있다.// `func1`과 `func2`는 동일하게 동작합니다. function func1(arg) { if (!arg) { arg = 'hello'; } console.log(arg) } function func2(arg) { arg = arg || 'hello'; // arg가 true면 arg = arg, false면 arg = 'hello' // ES2015에서 '기본 매개변수' 문법이 생긴 뒤로는 잘 쓰이지 않지만, 간혹 ES2015 미만 코드에서 보인다! console.log(arg); }
삼항 연산자 (Ternary Operator)
-
삼항 연산자도 단축 평가와 마찬가지로 평가할 필요가 없는 부분은 평가하지 않는다.
-
if...else
를 대신하는 용도로도 자주 사용된다.
증가/감소 연산자 (Increment/Decrement Operator)
++
/--
연산자는 피연산자의 값을 1 증가 / 1 감소시킨다.++
/--
연산자를 피연산자 앞에 쓰면, 그 표현식은 값을 증가시키고 뒤의 결과값을 반환한다.++
/--
연산자를 피연산자 뒤에 쓰면, 그 표현식은 값을 증가시키기 전의 피연산자를 그대로 반환한다.
할당 연산자 (Assignment Operator)
=
,+=
,-=
등등의 연산자들이 모두 할당 연산자이다.- 할당 연산자에 대한 표현식의 결과값은
왼쪽 피연산자에 실제로 할당된 값
이다.
연산자 우선순위 (Operator Precedence)
- 연산자 우선순위 MDN 문서
- 같은 연산자를 연이어 사용한 경우가 아니라면, 코드 가독성을 위해 가장 높은 우선순위를 갖는 연산자인 괄호로 둘러싸 주는 것이 좋다.
연산자 결합 순서 (Operator Associativity)
-
대부분의 경우 결합 순서가 명확히 눈에 보인다. (주로 좌 결합성)
-
다만, 거듭제곱 연산자, 할당 연산자, 삼항 연산자가 우 결합성을 가진다는 사실은 예외이므로 기억해둬야 한다.
-
결합 순서와 계산 순서는 다르다.
// 거듭제곱 연산자 (오른쪽부터 평가) 2 ** 2 ** 3; // 256 2 ** (2 ** 3); // 256 // 할당 연산자 (오른쪽부터 평가) let x, y, z; z = y = x = 1 z = (y = (x = 1)) // 삼항 연산자 (왼쪽부터 평가) a ? b : c ? d : e ? f : g a ? b : (c ? d : (e ? f : g))
값을 비교하는 여러 가지 방법
- 두 값이 같은지 비교하는 방법
==
,!=
===
,!==
Object.is
-
추상적 동일성 (Abstract Equality)
-
==
연산자는 두 피연산자의 타입이 다를 때는 타입을 변환한 후 비교한다. -
null check를 할 때에는
==
연산자가 주로 사용된다.null
과undefined
두 값을 동일한 것으로 취급한다.null
과undefined
를 이 두 값을 제외한 다른 값과 비교했을 때 항상 결과값이false
가 된다.
null == undefined; // true null == 0; // false null == ''; // false undefined == false; // false undefined == NaN; // false
-
-
엄격한 동일성 (Strict Equality)
-
===
,!==
연사자는 두 피연산자의 타입이 다른 경우 무조건false
를 반환한다. -
number
타입에 대한 비교에서의 예외// `===` 연산에서, `NaN`은 number 타입의 **모든** 값과 다릅니다. 이는 자기 자신에 대해서도 마찬가지입니다. NaN === NaN; // false Number.isNaN(NaN); // true // `0`과 `-0`은 서로 다른 값이지만, `===` 연산은 이 둘을 같은 것으로 취급합니다. 0 === -0; // true
-
-
Object.is
-
Object.is
정적 메소드는 두 인수가 정말 같은 값인지를 검사한다. -
예외
Object.is(NaN, NaN); // true Object.is(0, -0); // false
-
펼침 연산자 (Spread Syntax)
- Spread 연산자를 사용하면 배열(or 객체)을 다른 배열(or 객체)에 쉽게 삽입할 수 있다.
-
배열
const arr1 = [3, 4]; const arr2 = [1, 2, ...arr1, 5]; // [1, 2, 3, 4, 5] // 이전에는 같은 작업을 하기 위해 `Array.prototype.concat` 메소드를 사용했습니다. [1, 2].concat(arr1).concat([5]) // [1, 2, 3, 4, 5]
- 삽입하면서 복사가 일어날 때 얕은 복사 를 한다.
- 함수 호출 시에도 Spread 문법을 사용할 수 있다. 이 때 배열의 모든 요소를 함수의 인수로 넘긴다.
-
객체
-
객체에 대해서 Spread 문법을 사용할 때는 자기 자신의(own) 열거 가능한(enumerable) 속성만을 복사한다.
const obj1 = {prop: 1}; const obj2 = {...obj1}; // 이전에는 같은 작업을 하기 위해 `Object.assign` 정적 메소드를 사용했습니다. Object.assign({}, obj1);
-
객체에 같은 이름의 속성이 존재한다면 나중에 선언된 속성의 값으로 덮어쓴다.
-
이 문법은 ES2018에 추가된 기능이라 아직은 브라우저 호환성이 완벽하지 않기 때문에 Babel 플러그인 또는 TypeScript 등의 트랜스파일러를 사용해야 한다.
-
분해대입 (Destructuring Assignment)
- 배열과 객체 안에 들어있는 값을 쉽게 추출해낼 수 있는 문법 (ES2015)
-
배열의 분해대입
-
변수의 선언과 동시에 배열의 요소를 해당 변수에 대입
const [a, b, c] = [1, 2, 3]; console.log(a, b, c); // 1 2 3
-
요소의 순서와 일치하는 변수가 좌측 목록에 없으면, 해당 요소는 무시
// 여기서 `2`, `4`는 무시됩니다. const [a, , c] = [1, 2, 3, 4]; console.log(a, c); // 1 3
-
이미 선언된 변수에 대해서도 분해대입 가능
let a, b; [a, b] = [1, 2]; console.log(a, b); // 1 2
-
중첩된 배열에 대해서도 분해대입 가능
const [a, b, [c, d]] = [1, 2, [3, 4]]; console.log(a, b, c, d); // 1 2 3 4
-
배열의 나머지를 새로운 배열로 만들고 싶을 때도 분해대입 사용 가능
const [a, b, ...c] = [1, 2, 3, 4, 5]; console.log(c); // [3, 4, 5]
-
-
객체의 분해대입
-
주로 이런 형태로 사용된다.
const {a, b} = {a: 1, b: 2}; console.log(a, b); // 1 2
-
배열과 객체가 함께 중첩되어 있는 경우에도 분해대입 가능
-
객체의 나머지 속성으로 새로운 객체를 만들고 싶다면 배열에서와 마찬가지로
...
을 붙여주면 된다. (ES2018 문법이라 브라우저 호환성이 떨어진다.)
-
-
분해대입의 기본값
-
분해대입 시, 만약 좌측 변수의 위치에 해당하는 값이 우측의 배열 혹은 객체에 존재하지 않으면 그곳에는 대입이 일어나지 않는다.
-
이 때, 좌측 변수에 기본으로 대입될 값을 미리 지정해둘 수 있다.
// `c` 위치에는 대입될 값이 없으므로, 기본값인 `3`이 대신 사용됩니다. let [a, b, c = 3] = [1, 2]; console.log(c); // 3
-
-
매개변수에서의 분해대입
function func({prop, array: [item1, item2, item3 = 4]}) { console.log(prop); console.log(item1); console.log(item2); console.log(item3); } // 1, 2, 3, 4가 차례대로 출력됩니다. func({prop: 1, array: [2, 3]});
// 매개변수에서 객체를 분해대입하는 코드가 많이 쓰이고 있다. function func1(name, age, address, country) { } // 특정 매개변수의 역할을 바로 알아보기 어렵고, 인자의 순서를 바꾸면 안된다. func1('신창선', 28, '성북구', '대한민국') function func2({name, age, address, country}) { // ... } // 매개변수의 역할을 쉽게 알 수 있고, 순서를 바꿔서 써도 상관이 없다. func2({ name: '신창선', age: 28, address: '성북구', country: '대한민국' })
브라우저 측 Javascript
API (Application Programming Interface)
- 애플리케이션을 프로그래밍할 수 있는 접점
DOM API
- Document Object Model, 문서 객체 모델
- DOM
- DOM 소개
- 트리
- Event Reference
- Web APIs
트리
- 여러 데이터가 계층 구조 안에서 서로 연결된 형태를 나타낸다.
- 용어
- 노드(node)
- 자식 노드(child node)
- 부모 노드(parent node)
- 뿌리 노드(root node)
- 잎 노드(leaf node)
- 조상 노드(ancestor node)
- 자손 노드(descendant node)
- 형제 노드(sibling node)
요소 선택하기
document.querySelector(selector)
- CSS 선택자를 통해 단일 요소 가져오기document.querySelectorAll(selector)
- CSS 선택자를 통해 여러 요소 가져오기el.querySelector(selector)
- CSS 선택자를 통해 단일 자식 요소 가져오기el.closest(selector)
- 엘리먼트의 조상 중에 CSS 선택자와 일치하는 가장 가까운 조상 요소 가져오기el.matches(selector)
- 해당 요소가 CSS 선택자와 일치하는지 검사하기 (return true / false)
요소 내용 조작하기
el.textContent
- 요소 본문을 가져오거나 변경할 때 사용하는 속성 (텍스트)el.innerHTML
- 요소 본문을 가져오거나 변경할 때 사용하는 속성 (HTML)- 사용자로부터 입력받은 텍스트를 innerHTML에 대입해서는 절대로 안된다. (Cross-site Scripting (XSS) 해킹 공격의 우려가 있다.)
요소 어트리뷰트 조작하기
el.hasAttribute(attrName)
- 어트리뷰트가 있는지 검사하기el.getAttribute(attrName)
- 어트리뷰트의 값 가져오기el.setAttribute(attrName, attrValue)
- 어트리뷰트 설정하기el.removeAttribute(attrName)
- 어트리뷰트 삭제하기
요소 클래스 조작하기
el.classList.add(className, ...)
- 클래스 추가- 이미 존재하는 클래스는 더 이상 붙이지 않는다.
el.classList.remove(className, ...)
- 클래스 삭제el.classList.contains(className)
- 클래스 포함 여부 검사
인라인 스타일 조작하기
el.style
- 요소의 인라인 스타일을 읽고 쓸 때 사용하는객체.camelCase
사용el.style.backgroundColor = '#000000'
- 요소의 배경색을 검은색으로 변경
댓글남기기