TIL 09 | JavaScript, variables, data types

ryan·2020년 7월 22일
0

JavaScript

목록 보기
10/23
post-thumbnail

프로그램에서 중요한 것은 무엇일까?

입력, 연산, 출력
+ 전송, CPU에 최적화된 연산, 메모리의 사용을 최소화

Variable(변수), let, rw(read/write)

변경될 수 있는 값을 말함.
변수를 만들 때 쓰는 keyword는 let(added in ES6), var, const가 있다.

let name = 'ryan';
console.log(name);

let이라는 keyword를 이용해서 name이라는 변수를 선언(declaration)했다. 그리고 선언함과 동시에 ryan이라는 변수의 값을 할당했다.
console 창에 ryan 출력

name = 'hello'
console.log(name);

다시 name이라는 변수에 hello라는 값을 다시 할당함
console 창에 hello 출력

Block scope

{
let name = 'ryan';
console.log(name);
name = 'hello';
console.log(name);
}
console.log(name);

curly braces(중괄호)를 이용해서, block을 이용해서 코드를 block 안에 작성하게 되면 block 밖에서는 block 안에 있는 내용을 볼 수가 없게 된다. 즉, console을 이용해서 name을 출력하면 아무 값도 나오지 않는다.

global scope

block을 쓰지 않고, 파일 안에 바로 정의해서 쓰는 변수들.

let globalName = 'global name';
{
let name = 'ryan';
console.log(name);
name = 'hello';
console.log(name);
console.log(globalName); * 출력 됨
}
console.log(name);
console.log(globalName); * 출력 됨

global scope은 어느 곳에서나 접근이 가능
global scope 변수들은 application이 실행되는 순간부터 끝날 때까지 항상 메모리에 탑재되어있기때문에 최소한으로 쓰는 것이 좋고, 가능하면 class나 함수, if나 for loop, 필요한 부분에서만 정의해서 쓴는 것이 좋다.

Variable, var (don't ever use this!)

(강의에서는 아직도 var를 쓰는 친구가 있다면 등을 한 대 SLAP! 하고, "쓰지마!"라고 하라고 하는데, 댓글 보니까 우리나라는 아직 많이 사용한다고 한다... ps.IE )
var을 쓰지 말아야하는 이유

1.var hoisting(move declaration form bottom to top)
console.log(age);
age = 4;
var age;

선언도 하기 전에 값을 할당하고, 값을 할당하기 전에도 값을 할당할 수 있다.

name = 4;
let name;

let를 쓰면 위 코드는 에러가 뜬다. 'let으로 선언하기 전에 값을 넣었잖아!'

2.has no block scope(block을 철저히 무시한다.)

{
	age = 4;
    var age;
}
console.log(age);
  • age 변수를 block 안에 선언했음에도 불구하고, console을 이용해서 age를 block 밖에서 출력하면 정상적으로 출력이 되어버림.
  • 초창기에는 이런 유연성을 가지고, 프로그램을 대충대충 만들었지만, 어느 정도 규모가 큰 프로젝트를 하다버면 선언하지않은 값들이 할당되는 등 이상한 일들이 발생한다. 이런 var의 위험성때문에 let이 나온 것!
  • but, compilability(호환성)을 언제나 염두해둘 것! 링크텍스트

Variable, const(constant), r(read only)

// Note!
// Immutable data types: primitive types, frozen objects (i.e obejct.freeze())
// Mutable data types: all obejcts by default are mutable in JS

한 번 할당하면 값이 절대 바뀌지 않는다.

  • use const whenever possible
  • only use let if variable needs to change.
  • favor inmutable data type always for a few reasons:
  • security: 해커들로부터의 보안
  • thread safety: application이 실행되면 한 가지의 process가 실행되고, 그 process 안에서는 다양한 thread가 동시에 돌아가면서 application이 효율적으로 빠르게 돌아가도록 도와주는데, 이 다양한 thread들이 동시에 변수에 접근해서 값을 변경 할 수 있는데, 이 동시에 값을 변경할 수 있다는 것은 위험하다는 것이다.
  • reduce human mistakes: 앞으로 변경될 좋은 이유가 없다면 웬만해서는 const를 사용해서 작성하는 것이 좋다. 이렇게 해야 나중에 직접 코드를 바꿀 때나, 다른 개발자가 코드를 변경할 때 실수를 방지해 줄 수 있다.
const daysInWeek = 7;
const maxNumber = 5;
const monthsInYear = 12;

값이 계속 변경될 수 있는 것은 'Mutable Data Type, let처럼', 값이 변경될 수 없는 것은 'Immutable Data Type, const처럼'

Variable types

  • primitive, single item: number, string, boolean, null, undefined, symbol
    -> 더 이상 작은 단위로 나눠질 수 없는 한 가지인 type.
  • object, box container
    -> single item들을 여러 개 묶어서 한 단위로, 한 박스로 관리할 수 있게 해주는 것.
  • function, first-class function
    -> 'first-class function'이 지원이 된다는 말은, 즉, function도 다른 data type처럼 할당이 가능하고, 그렇기때문에 함수의 parameter, 인자로도 전달이 되고, 함수의 return type으로도 function을 return 할 수 있는 것이 가능하다.

primitive types

number

C, JAVA 언어처럼 얼마나 사이즈를 할당할 것인지 생각할 필요없이 javascript는 number type만 사용하면 된다.

const count = 17; // integer, 정수
const size = 17.1 // decimal number, 10진수
console.log(`value: ${count}, type: ${typeof count}`); // value: 17, type: number
console.log(`value: ${size}, type: ${typeof size}`); // value: 17.1, type: number

number - special numeric values: infinity, -infinity, NaN

대부분의 프로그래밍 언어에도 적용이 되어있듯이, 특별한 값이 미리 정해진 것이 있다.

const infinity = 1 / 0;
const negativeInfinity = -1 / 0;
const nAn = 'not a number' / 2;
console.log(infinity); // Infinity
console.log(negativeInfinity); // -Infinity
console.log(nAn); // NaN

연산할 때, 값이 valid한 값인지 확인하고 연산하는 것이 중요하다.

bigInt (fairly new, don't use it yet)

javascript에서 number는 -253 ~ 253까지 범위의 숫자만 표현이 가능한데, 최근에 bigInt라는 type이 추가되었다. 두 번재 코드 처럼 숫자 끝에 n만 붙이면 type이 number가 아닌 bigInt로 간주되어진다.

const bigInt = 1234567890123456789012345678901234567890; // over (-2**53 ~ 2**53)
console.log(`value: ${bigInt}, type= ${typeof bigInt}`); // value: 1.2345678901234568e+39, type= number
Number.MAX_SAFE_INTEGER;

const bigInt = 1234567890123456789012345678901234567890n; // over (-2**53 ~ 2**53)
console.log(`value: ${bigInt}, type= ${typeof bigInt}`); // value: 1234567890123456789012345678901234567890, type= bigint
Number.MAX_SAFE_INTEGER;

string

다른 프로그래밍 언어에서 한 가지의 character만 들어있는 data type이 따로있지만, javascript에서는 한 가지의 글자든, 여러개의 글자든 모두 다 string type으로 할당이 되고, 일반 string과 다른 변수를 '+'기호를 이용해서 string 연결할 수 있다.

const char = 'c';
const brendan = 'brendan';
const greeting = 'hello ' + brendan;
console.log(`value: ${greeting}, type: ${typeof greeting}`);

const helloBob = `hi ${brendan}!`; //template literals (string)
-> ``(backtick)을 사용해서 string(hi)을 적고, $기호와 {}를 이용하면, 변수의 값(brenden)이 자동적으로 붙여져서 나온다.
console.log(`value: ${helloBob}, type: ${typeof helloBob}`); // hi brendan!, type: string

console.log(`value: ${helloBob}, type: ${typeof helloBob}`);
console.log('value: ' + helloBob + ',' + ' type: ' + typeof helloBob);
-> ``(backtick)을 사용하지않는 기존의 출력 방법은 번거롭다.

boolean

True(참), False(거짓)

false: 0, null, undefined, NaN, ''
true: any other value

const canRead = true;
const test = 3 < 1; // false
console.log(`value: ${canRead}, type: ${typeof canRead}`); // value: true, type: boolean
console.log(`value: ${test}, type: ${typeof test}`); // value: false, type: boolean

null

let nothing = null;
console.log(`value: ${nothing}, type: ${typeof nothing}`); // value: null, type: object

-> null이라고 할당하는 경우에는 nothing이라는 변수가 텅텅비어있는 empty 값이라는 것을 지정해주는 것.

undefined

let x;
let x = undefined; // let x;와 같은 경우라고 보면 됨.
console.log(`value: ${x}, type: ${typeof x}`); // value: undefined, type: undefined

-> 선언은 되었지만 값이 지정되어있지않다.

symbol, create unique identifiers for objects

symbol은 나중에 다른 자료구조에서 고유한 식별자가 필요하거나, 아니면 동시에 다발적으로(concurrently) 일어날 수 있는 코드에서 우선순위를 주고 싶을 때 사용. 간혹, 식별자를 string을 사용해서 쓰는 경우가 있는데, string은 다른 모듈이나 다른 파일에서 동일한 string을 썼을 때, 동일한 식별자로 간주된다. 하지만, 반대로 symbol 같은 경우에는 동일한 (밑에 코드) 'id'를 이용해서 symbol을 만들었지만, 이 두가지의 symbol은 다른 경우다.

const symbol1 = Symbol('id');
const symbol2 = Symbol('id');

console.log(symbol1 === symbol2); // false

-> 동일한 지 확인

만약에 string을 같은 것을 사용하고, 동일한 symbol을 사용하고 있다면,

const gsymbol1 = Symbol.for('id');
const gsymbol2 = Symbol.for('id');
console.log(gsymbol1 === gsymbol2); // true
  • symbol은 바로 출력하면 에러가 발생
console.log(`value: ${symbol1}, type: ${typeof symbol1}`); // ... Cannot covert a Symbol value to a string at...
  • 따라서 항상 .decription을 사용해서 string으로 변환해서 출력을 해야한다.
console.log(`value: ${symbol1.description}, type: ${symbol1}`); // value: id, type: symbol

object, real-life object,data structure

-> 우리가 일상생활에서 보는 물건과 물체들을 대표할 수 있는 Box형태를 말한다. 그냥 변수, name, age는 아무것도 설명이 되지않지만, 'ryan', 100이라는 object를 만들어서 ryan의 이름은 ryan이고, 나이는 100살이라고 할 수 있다.
const ryan = { name: 'ryan', age: 100 };
-> ryan은 const로 지정되어있어서, 한 번 할당된 object는 다시는 변경이 불가하다. 하지만, ryan object 안에는 name과 age라는 변수들이 존재해서 ryan.name, ryan.age, 이런식으로하면 각 변수가 가리키는 memory에 다른 값으로 할당이 가능하다.
그래서,

const ryan = {
    name: 'ryan',
    age: 100
};
ryan.age = 20;
-> ryan의 age는 20이라고 변경이 가능하다. 

Primitive type vs Object type 저장 방식

Primitive type과 Object type은 type에 따라서 value(값) 다른 방식으로 저장된다.
primitive type은 value(값) 자체가 메모리에 저장된다.

let name = ryan; // ryan이 메모리에 바로 저장된다.

object type 너무 커서 메모리에 한 번에 다 저장될 수 없다.

const ryanInfo = {
	name: 'ryan',
       'age: 32'
};

const ryanInfo라고 선언하고, object를 할당하게 되면, ryanInfo가 가리키는 곳에는 ref(reference)가 있다. ref는 실제로 object를 가리키고 있는 곳이다. 이 ref를 통해서 실제로 object 담겨있는 메모리를 가리키게 되는 것이다. 그래서 const ryanInfo라고 하면, ryanInfo가 가리키는 ref만 잠겨서 ryanInfo가 다른 object로 변경하는 것이 불가능하지만, ryanInfo의 name과 age를 바꿀 수 있는 것은 이 이유 중에 하나이다.
-> 따라서, primitive type은 value로 값이 저장되고, object type은 object가 가리키는 ref에 메모리에 저장된다라고 이해하면된다.

Dynamic typing: dynamically typed language

C, JAVA 언어는 static typed language.
-> 변수를 선언할 때, 어떤 타입인지 결정해서 type을 같이 선언한다.

javascript 언어는 선언할 때, 어떤 타입인지 선언하지않고, run time, 프로그램이 동작할 때, 할당된 값에 따라서 type이 변경될 수 있다는 것을 얘기한다. 이런 dynamic typed language는 좋은 아이디어가 있을 때, 빠르게 프로토타입을 하기에는 유용하게 쓸 수 있는 언어지만, 다수의 엔지니어들 아니면 어느 정도 규모가 있는 프로젝트를 만들 때, dynamic typed 대문에 발에 불똥이 떨어질 수 있다.

예시)

let text = 'hello';
console.log(`value: ${text}, type: ${typeof text}`); // value: hello, type: string

-> 'hello'라는 string을 할당하게 되면, text는 string이라는 변수가 된다.

text = 1; 
console.log(`value: ${text}, type: ${typeof text}`); // value: 1, type: number

-> text에 다시 숫자 1을 할당하게 되면, type이 number로 변경이 된다.

text = '7' + 5;
console.log(`value: ${text}, type: ${typeof text}`); // value: 75, type: string

-> text에 '7' + 5; 를 할당하면, javascript engine에서 string('7')에 더하기가 있어서 number(5)를 string으로 변환해서 string + string을 해주게 되어 sting으로 type이 변환되면서 75가 된다.

text = '8' / '2';
console.log(`value: ${text}, type: ${typeof text}`); // value: 4, type: number

-> number가 들어있는 string에 나누기 연산자를 입력했네? 그럼 number와 number를 나누자! 그래서 type이 number가 되버린다.

=> Dynamic typing 때문에 뒤통수를 많이 얻어맞아서, TS(TypeScript, javascript 위에 type이 올려져서 나온 언어)가 나오게 된다.




### words
>- hoist: 끌어올려주다.
- hoisting: 어디에 선언했냐에 상관 없이, 항상 제일 위로 선언을 끌어올려주는 것.
-	constant: 일정한, 불변의, 상수
-	mutable: 변하기 쉬운
- immutable: 불변의
profile
👨🏻‍💻☕️ 🎹🎵 🐰🎶 🛫📷

0개의 댓글