특정 조건에 따라 참 / 거짓을 판별하여 각가 다른 값을 출력해주는 연산자
조건 ? true : false
예시
const array = [];
let text = '';
if (array.length === 0) {
text = '배열이 비어있습니다.';
} else {
text = '배열이 비어있지 않습니다.';
}
console.log(text)
위와 같이 특정조건에 따라
if/else
로만 구분하여text
값을 다르게 출력해야하는 경우
아래와 같이 작성할 수 있습니다.
const array = [];
let text = array.length === 0 ? '배열이 비어있습니다.' : '배열이 비어있지 않습니다.';
console.log(text)
라인의 길이가 너무 길어진다면 아래와 같이 작성하기도 합니다.
const array = [];
let text = array.length === 0
? '배열이 비어있습니다'
: '배열이 비어있지 않습니다.';
console.log(text);
특정 조건의 참/거짓에 따라 여러개의 케이스를 작성하고 싶다면 아래와 같이 작성하면 됩니다.
조건
? ((true 결과1), (true 결과2))
: ((false 결과1), (false 결과2));
}
Truthy : true 같은거...
Falsy : false 같은거...
- undefined - 자료형이 없는 상태 (변수를 선언하고 값을 할당하지 않은 상태)
- null - 빈 객체 (변수를 선언하고 빈 값(null)을 할당한 상태)
- 0
- '' - 빈 문자열
- NaN - Not A Number - 문자열을 숫자로 변환하는 parseInt 함수를 사용하게 될 때 볼 수 있음
이 외의 값들은 모두 Truthy
아래의 상황처럼
print()
함수의 파라미터에 값이 비어진채로 실행된다면
function print(person) {
console.log(person.name);
}
const person = {
name: 'John'
};
print()
TypeError: Cannot read property 'name' of undefined
에러를 호출함
때문에 object가 주어지지 않았을때 경우를 생성하면 에러를 피할 수 있다, 하지만...
function print(person) {
if (person === undefined) {
return;
}
console.log(person.name);
}
const person = {
name: 'John'
};
print();
만약 print에 null 값이 전달되면
TypeError: Cannot read property 'name' of null
에러를 호출한다
그러면 또 print()함수에 조건을 추가해줘야 하는 번거로움이 있는데
아래 코드처럼 (!person)으로 한번에 Falsy한 값으로 넘겨버리면
undefined
와null
모두 Falsy한 값의 범주 안에 있기 때문에 한번에 처리한다
function print(person) {
if (!person) {
console.log('person이 없네요');
return;
}
console.log(person.name);
}
const person = null;
print(person);
논리연산자
(&&, ||)
를 사용할 때 무조건 true 혹은 false 값을 사용하는 것은 아님
문자열이나 숫자, 객체를 사용할 수도 있고, 해당 값이 Truthy하냐 Falsy하냐에 따라 결과가 달라짐
예를 들어 아래와 같은 코드가 있을 때
const dog = {
name: '멍멍이'
};
function getName(animal) {
return animal.name;
}
const name = getName(dog);
console.log(name); // 멍멍이
getName()
에 제대로 된 객체가 주어지지 않는다면animal
객체가undefined
가 되고
undefined
에서는name
값을 조회할 수 없기 때문에 에러가 발생함
const name = getName();
console.log(name); // Error
그렇다면
animal
이 제대로 주어졌을 때만name
을 조회하고
그렇지 않을때는undefined
를 반환하게 하려면 아래와 같이 하면 됨
const dog = {
name: '멍멍이'
};
function getName(animal) {
if (animal) {
return animal.name;
}
return undefined
}
const name = getName();
console.log(name); // 멍멍이
위와 같은 코드를 논리 연산자를 사용하면 코드를 단축 시킬 수 있다.
const dog = {
name: '멍멍이'
};
function getName(animal) {
return animal && animal.name;
}
const name1 = getName(dog);
console.log(name1); // 멍멍이
const name2 = getName();
console.log(name2); // undefined
&&
연산자
A && B
연산자를 사용하게 될 때
A
가Truthy
한 값이라면,B
가 결과값이 됨
A
가Falsy
한 값이라면,A
가 결과값이 됨 (Falsy
한 값 그대로 출력)
console.log(true && 'hello'); // hello
console.log(false && 'hello'); // false
console.log('hello' && 'bye'); // bye
console.log(null && 'hello'); // null
console.log(undefined && 'hello'); // undefined
console.log('' && 'hello'); // ''
console.log(0 && 'hello'); // 0
console.log(1 && 'hello'); // hello
console.log(1 && 2); // 2
||
연산자
A || B
연산자를 사용하게 될 때
A
가Truthy
한 값이라면A
가 결과값이 됨
A
가Falsy
한 값이라면B
가 결과값이 됨
console.log(true || 'hello'); // true
console.log(false || 'hello'); // hello
console.log('hello' || 'bye'); // hello
console.log(null || 'hello'); // hello
console.log(undefined || 'hello'); // hello
console.log('' || 'hello'); // hello
console.log(0 || 'hello'); // hello
console.log(1 || 'hello'); // 1
console.log(1 || 2); // 1
function 이름(params = value) {
code
}
원의 넓이를 구하는 함수
function calculateCircleArea(r) {
return Math.PI * r * r;
}
const area = calculateCircleArea(4);
console.log(area); // 50.26548245743669
만약
r
값을 넣지 않으면NaN
에러 호출
때문에r
값이 주어지지 않았다면 기본 값을 1로 사용하도록 설정
function calculateCircleArea(r) {
const radius = r || 1;
return Math.PI * radius * radius;
}
const area = calculateCircleArea();
console.log(area); // 3.141592653589793
function calculateCircleArea(r = 1) {
return Math.PI * r * r;
}
const area = calculateCircleArea();
console.log(area); // 3.141592653589793
const calculateCircleArea = (r = 1) => Math.PI * r * r;
const area = calculateCircleArea();
console.log(area); // 3.141592653589793
const myFunc(a) { // 여기서 a는 파라미터
console.log(a); // 여기서 a는 인자
}
myFunc('Hello World'); // 여기서 'Hello World'는 인자
함수에서 값을 넣어줄 때, 그 값들이 인자
함수에서 값을 읽을 때, 그 값들이 파라미터
function isAnimal(text) {
return (
text === '고양이' || text === '개' || text === '거북이' || text === '너구리'
);
}
console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false
위와 같이 코드를 짜면 값이 많아질수록 코드가 길어짐
이를 해결하기 위해 아래와 같이 배열을 만들고includes
함수를 씀
function isAnimal(name) {
const animals = ['고양이', '개', '거북이', '너구리'];
return animals.includes(name);
}
console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false
화살표 함수로 작성
const isAnimal = name => ['고양이', '개', '거북이', '너구리'].includes(name);
console.log(isAnimal('개')); // true
console.log(isAnimal('노트북')); // false
if
문으로 작성
function getSound(animal) {
if (animal === '개') return '멍멍!';
if (animal === '고양이') return '야옹~';
if (animal === '참새') return '짹짹';
if (animal === '비둘기') return '구구 구 구';
return '...?';
}
console.log(getSound('개')); // 멍멍!
console.log(getSound('비둘기')); // 구구 구 구
switch case
문으로 작성
function getSound(animal) {
switch (animal) {
case '개':
return '멍멍!';
case '고양이':
return '야옹~';
case '참새':
return '짹짹';
case '비둘기':
return '구구 구 구';
default:
return '...?';
}
}
console.log(getSound('개')); // 멍멍!
console.log(getSound('비둘기')); // 구구 구 구
위의 두 코드 모두 문제는 없지만 훨씬 스마트하게 작성 가능
해당 코드는 객체안의 변수에 지정된 값을 불러오는 형태
function getSound(animal) {
const sounds = {
개: '멍멍!',
고양이: '야옹~',
참새: '짹짹',
비둘기: '구구 구 구'
};
return sounds[animal] || '...?';
}
console.log(getSound('개')); // 멍멍!
console.log(getSound('비둘기')); // 구구 구 구
해당 코드는 객체안의 함수를 실행시키는 형태
function makeSound(animal) {
const tasks = {
개() {
console.log('멍멍');
},
고양이() {
console.log('고양이');
},
비둘기() {
console.log('구구 구 구');
}
};
if (!tasks[animal]) {
console.log('...?');
return;
}
tasks[animal]();
}
getSound('개');
getSound('비둘기');
const object = { a: 1, b: 2};
const { a, b } = object;
console.log(a); // 1
console.log(b); // 2
const object = { a: 1, b: 2 };
function print({ a, b }) {
console.log(a)
console.log(b)
}
print(object); // 1 2
const object = { a: 1 };
function print({ a, b = 2 }) {
console.log(a);
console.log(b);
}
print(object);
// 1
// 2
const object = { a: 1 };
const { a, b = 2 } = object;
console.log(a); // 1
console.log(b); // 2
비구조화 할당을 하는 과정에서 선언할 값의 이름을 바꾸는 법
const animal = {
name: '멍멍이',
type: '개'
};
const nickname = animal.name;
console.log(nickname); // 멍멍이
위의 코드에서
animal.name
값을nickname
값에 담고 있는데,
이름이 같게 할당하려면{ name } = animal
의 형태로 쓰면 되지만
이름을 달리 할당하려면{ name: nickname } = animal
의 형태로 써야함
animal
객체는 건드리지 않음
const animal = {
name: '멍멍이',
type: '개'
};
const { name: nickname } = animal
console.log(nickname);
위 코드는 "
animal
객체 안에 있는name
을nickname
이라고 선언하겠다" 라는 의미
비구조화 할당은 객체뿐만 아니라 배열에서도 할 수 있음
아래의 문법은 배열 안에 있는 원소를 다른 이름으로 새로 선언하고 싶을 때 사용하면 유용함
객체 비구조화 할당과 마찬가지로 기본값 지정 가능
const array = [1, 2, 3];
const [one, two, three = 3] = array;
console.log(one); // 1
console.log(two); // 2
console.log(three); // 3
아래의 코드에서 깊은 곳에 있는 값(name, languages, value)을 꺼내려 함
const deepObject = {
state: {
information: {
name: 'velopert',
languages: ['korean', 'english', 'chinese']
}
},
value: 5
};
비구조화 할당 문법을 두번 이상 사용하는 방법
const deepObject = {
state: {
information: {
name: 'velopert',
languages: ['korean', 'english', 'chinese']
}
},
value: 5
};
const { name, languages } = deepObject.state.information;
const { value } = deepObject;
const extracted = {
name,
languages,
value
};
console.log(extracted); // {name: "velopert", languages: Array[3], value: 5}
아래 두 코드는 같은 의미임
만약key
이름으로 선언된 값이 존재한다면 바로 매칭시켜주는 문법
(object-shorthand 문법)
const extracted = {
name,
languages,
value
}
const extracted = {
name: name,
languages: languages,
value: value
}
한번에 모두 추출하는 방법
const deepObject = {
state: {
information: {
name: 'velopert',
languages: ['korean', 'english', 'chinese']
}
},
value: 5
};
const {
state: {
information: { name, languages }
},
value
} = deepObject;
const extracted = {
name,
languages,
value
};
console.log(extracted); // {name: "velopert", languages: Array[3], value: 5}
확산, 퍼뜨리다의 뜻을 갖고 있는 Spread는 객체 혹은 배열을 퍼뜨리는 문법
아래와 같이 선언하면
...Object
부분에 해당Object
의 값들을 모두 받아옴
Object
를 확산 시킴
const slime = {
name : '슬라임'
};
const cuteSlime = {
...slime,
attribute: 'cute'
}
const purpleCuteSlime = {
...cuteSlime,
color: 'purple'
}
console.log(slime); // { name: '슬라임' }
console.log(cuteSlime); // { name: '슬라임', attribute: 'cute' }
console.log(purpleCuteSlime); // { name: '슬라임', attribute: 'cute', color: 'purple' }
Spread
연산자는 배열에서도 사용할 수 있음
const animals = ['개', '고양이', '참새'];
const anotherAnimals = [...animals, '비둘기'];
console.log(animals); // ['개', '고양이', '참새']
console.log(anotherAnimals); // ['개', '고양이', '참새', '비둘기']
배열에서 spread 연산자를 다중 사용할 수 도 있음
객체가 다중사용이 안되는 이유 -> 당연함 객체는key
값의 중복을 허용하지 않기 때문
const numbers = [1, 2, 3, 4, 5];
const spreadNumbers = [...numbers, 1000, ...numbers];
console.log(spreadNumbers); // [1, 2, 3, 4, 5, 1000, 1, 2, 3, 4, 5]
나머지라는 뜻을 갖고 있는 Rest는 객체 혹은 배열에서 나머지 값들을 담음
Spread
와의 차이점은 함수의 파라미터에서도 사용이 가능하다는 점나머지라는 뜻과 걸맞게 비구조화 할당을 통해 사용할 시 반드시 구문 끝에 위치해야함
객체에서 사용할 때는 비구조화 할당 문법과 함께 사용함 (배열도 마찬가지)
주로 사용 할때는rest
키워드를 쓰긴 하지만, 반드시 이름이rest
일 필요는 없음
const purpleCuteSlime = {
name: '슬라임',
attribute: 'cute',
color: 'purple'
};
const { color, ...rest } = purpleCuteSlime;
console.log(color); // purple
console.log(rest); // { name: '슬라임', attribute: 'cute' }
const { attribute, ...slime } = rest;
console.log(attribute); // cute
console.log(slime); // { name: '슬라임' }
const numbers = [0, 1, 2, 3, 4, 5, 6]
const [one, ...rest] = numbers;
console.log(one); // 0
console.log(rest); // [1, 2, 3, 4, 5, 6]
파라미터로 넣어준 모든 값들을 받아줌
function sum(...rest) {
return rest
}
const result = sum(1, 2, 3, 4, 5, 6);
console.log(result); // [1, 2, 3, 4, 5, 6]
배열을 인자로 넣을 때
rest
문법을 쓰면 배열 안의 값들을 차례로 인자로 넣어줌
iterable한 배열에서만 동작함 -> 객체는 에러 호출
function sum(...rest) {
return rest.reduce((acc, current) => acc + current, 0);
}
const numbers = [1, 2, 3, 4, 5, 6];
const result = sum(...numbers);
console.log(result);
Scope란 변수 or 함수를 선언하게 될 때 해당 변수 또는 함수가 유효한 범위를 의미
ES6 이후로 자주 쓰이는
let
과const
기준
const value = 'hello!'; // Global Scope
function myFunction() {
const value = 'bye!'; // Function Scope
if (true) {
const value = 'world'; // Block Scope
console.log('block scope: ');
console.log(value);
}
console.log('function scope: ');
console.log(value);
}
myFunction();
console.log('global scope: ');
console.log(value);
ES6이후로는 거의 쓰이지 않는
var
기준
var
는Function Scope
로 선언 되기 때문에 if문 블록 내부에서 선언한value
값이
블록 밖의value
에도 영향을 미치게 됨
var value = 'hello!';
function myFunction() {
var value = 'bye!';
if (true) {
var value = 'world';
console.log('block scope: ');
console.log(value); // world
}
console.log('function scope: ');
console.log(value); // world
}
myFunction();
console.log('global scope: ');
console.log(value); // hello
Hoisting
이란 아직 선언되지 않은 함수/변수를 "끌어올려서" 사용 할 수 있는 JS의 작동 방식피해야하는 현상
myFunction();
function myFunction() {
console.log('hello world!');
}
위 코드에서는
myFunction
함수를 선언하기 전에myFunction()
을 호출함
동작시켜보면 함수가 아직 선언 되지 않았음에도 코드는 정상적으로 작동하게 됨
이유는Js Engine
이 위 코드를 해석하는 과정에서 아래 코드와 같이 받아들이기 때문
아래와 같이 함수를 끌어올리는 현상을Hoisting
이라고 함
function myFunction() {
console.log('hello world!');
}
myFunction();
var
아래와 같은 코드를 실행 시키면
ReferenceError
가 호출됨
값이 선언되지 않았기 때문
console.log(number); // Error
아래의 코드를 실행하면
undefined
출력
console.log(number); // undefined
var number = 2;
이유는 아래의 JS가 아래의 코드로 받아들이기 때문
var number;
console.log(number); // undefined
number = 2;
let
과 const
let
과const
는Hoisting
이 발생하지 않고, 바로Error
를 호출함