Variable이랑 constant가 대조되는(?) 애들이란 건 처음 알았다.
찾아보니 아예 수학적으로 널리 통용되고 있는 언어였는데..
Variable(변수): rw(Read/write)
-읽고 쓰는 게 가능
variable은 메모리 저장방식에 따라 primitive랑 object 타입으로 나뉨
primitive: 값 자체에 할당이 됨
Immutable data types: primitive types, frozen objects (i.e. object.freeze())
-데이터 자체를 절대 변경하지 못하는 타입
object: 너무 커서 메모리에 한번에 올라가지 못함, 오브젝트가 가리키는 메모리가 저장된다.
Mutable data types: all objects by default are mutable in JS
-계속 스스로 변경이 가능한 타입ex) const ellie => 다른 오브젝트로 변경이 불가능하지만 name이나 age는 계속해서 바뀌는 거
Constant: r(read only)
-그래서 계속해서 변할일이 없다면 웬만하면 const로 작성하는 것이 좋음
console.log('my' + 'cat');
console.log('1' + '2');
console.log(`string literals: 1 + 2 = ${1 + 2}`);
''(싱글 코트)와 ``(백틱)의 차이점을 계속 언급하셔서 관련 자료를 찾아보았다
출처: https://velog.io/@sunaaank/js-backtick)
*요약한줄: 백틱을 사용하면 별도의 코드없이 자체적으로 줄바꿈이 되므로 싱글 코트보다 코드의 양을 줄일 수 있다.
console.log(1 + 1); //add(더하기)
console.log(1 - 1); //substract(빼기)
console.log(1 / 1); //divide(나누기)
console.log(1 * 1); //multiply(곱하기)
console.log(5 % 2); //remainder(나머지 구하기)
console.log(2 ** 3); //exponentiation(2의 3승)
let counter = 2;
const preIncrement = ++counter;
// 위 코드와 같은 코드
// counter = counter + 1;
// preIncrement = counter;
// 해석: counter라는 변수에 1을 더한 값을 preIncrement에 할당해라
console.log(`preIncrement: ${preIncrement}, counter: ${counter}`);
//console로 확인해보면 preIncrement = 3, counter= 3으로 출력되며
이처럼 preIncrement와 counter에 같은 값이 할당된 걸 볼 수 있음
const postIncrement = counter++;
// postIncrement = counter;
// counter = counter + 1;
// 위와 반대로 먼저 counter의 값을 postIncrement에 넘긴다음에 +1을 연산함
console.log(`postIncrement: ${postIncrement}, counter: ${counter}`);
//위에서 2에다 1을 더해서 postIncrement는 3, counter에는 그 후에 +1을 해서 4로 찍힘
const preDecrement = --counter;
console.log(`preDecrement: ${preDecrement}, counter: ${counter}`);
// preDecrement: 3, counter: 3
const postDecrement = counter--;
console.log(`postDecrement: ${postDecrement}, counter: ${counter}`);
// postDecrement: 3, counter: 2
let x = 3;
let y = 6;
x += y; // x = x + y;
x -= y;
x *= y;
x /= y;
-값을 대입할 때 사용
console.log(10 < 6); //less than
console.log(10 <= 6); // less than or equal
console.log(10 > 6); // greater than
console.log(10 >= 6); // greater than or equal
-피연산자 사이의 상대적인 크기를 판단하여, true와 false를 반환한다.
const value1 = true;
const value2 = 4 < 2;
console.log(`or: ${value1 || value2 || check()}`);
console.log(`and: ${value1 && value2 && check()}`);
Tip: or나 and를 쓸 때 무거운 연산일 수록 호출식을 뒤에 놓아야 효율적인 프로그래밍이 된다.
// often used to comporess long if-statement
// nullableObject && nullableObject.something
let nullableOject = null;
if (nullableOject != null) {
nullableOject.something;
}
function check() {
for (let i = 0; i < 10; i++) {
//wasting time
console.log('😱');
}
return true;
}
console.log(!value1);
const stringFive = '5';
const numberFive = 5;
// == loose equality, with type conversion(타입이 달라도 안에 있는 내용이 같으면 같다고 인식)
console.log(stringFive == numberFive);
console.log(stringFive != numberFive);
// === strict equality, no type conversion(타입을 신경써서, 타입이 다르면 다르다고 인식)
// 그래서 웬만하면 정확성을 위해 strict(===)를 사용해 식을 작성하는 것이 좋다!
console.log(stringFive === numberFive);
console.log(stringFive !== numberFive);
// object equality by reference
const ellie1 = { name: 'ellie' };
const ellie2 = { name: 'ellie' };
const ellie3 = ellie1;
console.log(ellie1 == ellie2); //ellie1과 ellie2는 레퍼런스가 다르므로 false
console.log(ellie1 === ellie2); //ellie1과 ellie2는 타입이 같아도 레퍼런스가 다르므로 false
console.log(ellie1 === ellie3); //ellie1과 ellie3는 레퍼런스가 같으므로 true
// equality - puzzler
console.log(0 == false); // 0은 false로 인식하므로 true
console.log(0 === false); // 0은 bollean type이 아니기 때문에 strict euality를 이용하게 되면 false
console.log('' == false); // empty 문자열은 false므로 true
console.log('' === false); // empty 문자열도 bollean타입이 아니기 때문에 false
console.log(null == undefined); // null과 undefined는 같은 것으로 간주하기 때문에 true
console.log(null === undefined); // null과 undefined는 다른 타입이기 때문에 false
-웬만하면 strict(===)을 사용
// if, else if, else
const name = 'ellie';
if (name === 'ellie') {
console.log('Welcome, Ellie!');
} else if (name === 'coder') {
console.log('You are amazing coder');
} else {
console.log('unkwnon');
}
// condition ? value1 : value2;
console.log(name === 'ellie' ? 'yes' : 'no');
// true면 ? 왼쪽에 있는 걸 출력, 아니면 : 뒤에 나오는 걸 출력
// use for multiple if checks
// use for enum-like value check
// use for multiple type checks in TS
const browser = 'IE';
switch (browser) {
case 'IE':
console.log('go away!');
break;
case 'Chrome':
case 'Firefox':
console.log('love you!');
break;
default:
console.log('same all!');
break;
}
// while loop, while the condition is truthy,
// body code is executed.
let i = 3;
while (i > 0) {
console.log(`while: ${i}`);
i--;
}
// do while loop, body code is excuted first,
// then check the condition.
// 먼저 블록을 실행한 다음 출력
do {
console.log(`do while: ${i}`);
i--;
} while (i > 0);
// for loop, for(begin; condition; step) 시작하는 문장; 어떤 condition인가가 중간에 오고,
어떤 스텝으로 마무리할지 구성돼있음
for (i = 3; i > 0; i--) {
console.log(`for: ${i}`);
}
for (let i = 3; i > 0; i = i -2) {
// inline variable declaration(블록 안에 let이라는 지역변수를 사용하는 경우)
console.log(`inline variable for: ${i}`);
}
for (let i = 0; i < 10; i++) {
for (let j = 0; j < 10; j ++) {
console.log(`i: ${i}, j:${j}`);
}
}
// Q1. iterate from 0 to 10 and print only even numbers(use continue)
// continue 사용하는 버전
for(let i = 0; i < 11; i++) {
if (i % 2 !== 0) {
continue;
}
console.log(`q1. ${i}`);
}
// 더 효율적인 버전
for(let i = 0; i < 11; i++) {
if (i % 2 === 0) {
console.log(`q1. ${i}`);
}
}
// Q2. iterate from 0 to 10 and print numbers until reaching 8 (use break)
for(let i = 0; i < 11; i++) {
if (i > 8) {
break;
}
console.log(`q2. ${i}`);
}