JavaScript

자바스크립트 공부 #2

kinggoddino 2024. 10. 4.

자바스크립트 뭔가 애가 유연하면서도 이상해서 맘에든다

그래도 파이썬이 더 좋아 ㅎㅎ

 

내용

더보기

1. 변수  -  var, let, const  /  호이스팅 

2. 생성자 함수  -  new

3. Computed property  -  [ ]

4. 메서드

  • assign()  /  keys()  /  values()  /  entries()  /  fromEntries()

5. 유일한 식별자

  • Symbol()  /  Symbol.for()  /  Symbol.keyFor  /  description
  • Object.getOwnPropertySymbols()  /  Reflect.ownKeys()

6. 수학 

  • toString()  /  Math  /  Math.ceil()  /  Math.floor()  /  Math.round()
  • toFixed()  /  isNaN()  /  parselnt()  /  parseFloat()
  • Math.random()  /  Math.max()  /  Math.min()  /  Math.abs()  /  Math.pow()  /  Math.sqrt()

7. 문자열

  • length  /  toUpperCase()  /  toLowerCase()
  • indexOf()  /  slice(n,m)  /  substring(n,m)  /  substr(n,m)
  • trim()  /  repeat(n)  /  codePointAt()

8. Array 메서드

  • push()  /  pop()  /  unshift()  /  shift()  /  splice(n,m,x)  /  slice(n,m) 
  • concat(arr2, arr3 ...)  /  forEach(fn)
  • indexOf()  /  includes()  /  find(fn)  /  findIndex(fn)  /  filter(fn)
  • reverse()  /  map(fn)  /  join()  /  split()  /  isArray()  /  sort(fn)
  • reduce()

9. 구조 분해 할당

  • 배열 구조 분해  -  할당  /  default 설정  /  반환값 무시  /  바꿔치기
  • 객체 구조 분해  -  할당  /  property명 지정  /  default 설정 

10. 나머지 매개변수, 전개구문

  • arguments  /  나머지 매개변수(Rest parameters) ...names
  • 전개 구문 (Spread syntax)

 

1. 변수 var, let, const

 

1-1. 호이스팅(hoisting)

스코프 내부 어디에서는 변수 선언은 최상위에 선언된 것 처럼 행동

var, let, const 는 모두 호이스팅을 일으킨다

 

 

1-2. TDZ

 

Temporal Dead Zone

TDZ 영역에 있는 변수들은 사용할 수 없음.


var는 TDZ 영향을 받지 않음.

== 할당 하기 전에도 사용할 수 있음.

 

let 과 const 는 TDZ 영향을 받는다. 

== 할당을 하기 전에는 사용을 할 수 없음.

-> 코드를 예측가능하게 하고, 잠재적 버그를 줄일 수 있다

 

 

1-3. 변수의 생성과정

 

var

1) 선언 및 초기화 단계 (초기화: undefined를 할당해주는 단계)

2) 할당 단계

 

let

1) 선언 단계

2) 초기화 단계

3) 할당 단계

 

const

1) 선언 + 초기화 + 할당

 

 

1-4. 스코프

 

var

: 함수 스코프(function-scoped)

: 함수 내에서 선언된 변수는 코드 블록 내에서만 유효하며, 외부에서는 접근할 수 없다

(함수내에서만 지역변수가 됨)

 

let, const

: 블록 스코프(block-scoped)

: 모든 코드 블록에서 선언된 변수는 코드 블록 내에서만 유효하며, 외부에서는 접근할 수 없다

(모든 코드블록 내에서 지역변수가 됨 - 코드블록 : 함수, if문, for문, while문 등)

 

 

tip : var는 이제 사용하지 않음. let과 const 만 권장됨

 


 

2. 생성자 함수 new

 

2-1. 객체 리터럴

let user = {
  name : 'Spino',
  age : 23,
}

 

2-2. 생성자 함수

비슷한 객체를 여러개 만들어야 할 때

ex) 회원, 상품 등

function User(name, age){  // 첫글자를 대문자로
  // this = {}  // new로 인한 알고리즘
  this.name = name;
  this.age = age;
  // return this;  // new로 인한 알고리즘
}

let user1 = new User('Spino', 23);  // new 연산자로 호출
let user2 = new User('Tyranno', 17);

 


 

3. Computed property

[대괄호] 로 묶어주면, 변수 a 에 할당된 값이 들어감

let a = 'age';

const user = {
  name = 'Spino',
  [a] = 23,  // age 대신 [a] 쓸수 있음
}
const user = {
  [1 + 4] : 5,  // 식 자체를 넣는 것도 가능
  ["안녕" + "하세요"] : "Hello"
}

> user  // 입력
< {5: 5, 안녕하세요: "Hello"}  // 반환

 

어떤게 키가 될 지 모르는 객체를 만들 때 유용하다

 

 

 

4. Methods

 

4-1. Object.assign() : 객체 복제

 

변수에는 객체 자체가 저장되는 것이 아니라,

객체가 들어있는 메모리 주소인 객체의 참조값만 저장된다

 

따라서 그냥 클론객체를 만들어서 해당 객체를 넣으면

객체가 복사되면서 들어가는 것이 아니라, 그냥 참조값만 복사된다.

== 그냥 동일한 객체 메모리 주소를 가르키고 있는 변수가 추가되는 것임

 

객체를 새롭게 복제하려면

Object.assign() 메서드를 사용해야한다

const newUser = Object.assign({}, user);  // 초기값 == 빈객체

const newUser = Object.assign({ gender : 'male' }, user);
// 초기값의 프로퍼티가 추가되거나, 덮어씌워짐

 

첫번째 매개변수 == 초기값

두번째 매개변수부터 들어온 객체들이 초기값에 병합된다

const user = { name : 'spino' };
const info1 = { age : 30 };
const info2 = { gender : 'male' }

Object.assign(user, info1, info2)  // 이렇게도 병합가능!

 

 

4-2. Object.keys() : 키 배열 반환

객체의 키들만 배열로 만들어서 반환한다

const user = {
  name : 'spino', 
  age : 23,
  gender : 'male',
}

Object.keys(user);  // ["name", "age", "gender"]

 

 

4-3. Object.values() : 값 배열 반환

객체의 값들만 배열로 만들어서 반환한다

const user = {
  name : 'spino', 
  age : 23,
  gender : 'male',
}

Object.values(user);  // ["spino", 23, "male"]

 

 

4-4. Object.entries() : 키/값 배열 반환

객체의 키와 값을 쌍으로 묶어서 반환한다 (배열안에 배열)

const user = {
  name : 'spino', 
  age : 23,
  gender : 'male',
}

Object.entries(user);
// [["name", "spino"], ["age",23], ["gender","male"]]

 

 

4-5. Object.fromEntries() : 키/값 배열을 객체로

위랑 반대개념

const arr =
[
  ["name", "spino"],
  ["age",23],
  ["gender","male"],
];

Object.fromEntries(arr);
// 암튼 객체로 만들어줌. 적기 귀찮

 


 

5. 심볼 (Symbol)

 

5-1. Symbol()

 

지금까지 객체의 property key 는 문자형으로 만들었다.

const obj = {
  1: "1입니다"  // 숫자나
  false: "거짓"  // 불린형으로 만들어도
}

Object.keys(obj);  // ["1", "false"] 문자형이 됨

 

<유일한 식별자>

Symbol()은 전체 코드에서 유일성을 보장한다.

유일한 식별자를 만들 때 사용함

const a = Symbol();
const b = Symbol();

console.log(a);  // Symbol()
console.log(b);  // Symbol()

console.log(a === b);  // false
console.log(a == b);  // false

 

문자열로 설명을 붙여줄 수도 있음. (디버깅할 때 편할거같다)

const id = Symbol("id");
const id2 = Symbol("id");

console.log(id);  // Symbol(id)
console.log(id2);  // Symbol(id)

console.log(id === id2);  // false
console.log(id == id2);  // false

 

그럼 이제 객체의 property key를

문자형이 아닌 심볼형으로 만들어보자

const id = Symbol("id");
const user = {
  name : "Spino",
  age : 23,
  [id] : "myid"
}

 

그런다음 user 객체를 출력해보면

> user
< {name: "Spino", age: 23, Symbol(id): "myid"}

> user[id]
< "myid"

Symbol 이 잘 적용되어서 나온다

 

하지만 method 를 사용해서 출력해보면

Object.keys(user);  // ["name", "age"]
Object.values(user);  // ["Spino", 23]
Object.entries(user);  // ["name":"Spino", "age":23]

Symbol 을 건너뛰고 나온다

얘네 뿐만 아니라

for ... in 문에서도 Symbol 은 걸리지 않고 출력된다

 

 

이렇게 꽁꽁 숨겨놓는 기능을 어디에 쓸 수 있을까?

 

특정 위치에 원본 데이터는 건드리지 않고 속성을 추가할 수 있다.

파이썬에서 캡슐화같은 개념인가부다

 

아래 5-5 에서 예시로 확인

 

 

암튼 Symbol 은 위와 같이 이름이 같더라도 다른 객체를 가르키고 있는데,

같은 객체를 가르켜야할 때도 있다

 

 

5-2. Symbol.for()

 

Symbol.for() : 전역 심볼

- 하나의 심볼만 보장받을 수 있음

- 없으면 만들고, 있으면 가져온다

- Symbol : 매번 다른 Symbol 값을 생성하지만,

- Symbol.for : 하나를 생성한 뒤 키를 통해 같은 Symbol을 공유함

const id1 = Symbol.for('id');
const id2 = Symbol.for('id');

id1 === id2  // true

 

 

5-3.

 

Symbol.keyFor

생성할 때 적었는 문자열 설명을 알려줌

const id1 = Symbol.for("id 입니다");
Symbol.keyFor(id1)  // "id 입니다"

 

description

비슷하게, 전역심볼이 아닌 심볼은 keyFor 대신 description 사용

const id2 = Symbol("id 입니다");
id2.description;  // "id 입니다"

 

 

5-4.

 

사실 Symbol을 완전히 숨길 수 있는 것은 아님

숨겨진 Symbol key 보는 법

 

Object.getOwnPropertySymbols()

//ex)
Object.getOwnPropertySymbols(user);  // [Symbol(id)]

심볼에 해당하는 프로퍼티만 확인할 수 있음 

 

Reflect.ownKeys()

// ex)
Reflect.ownKeys(user);  // ["name", "age", Symbol(id)]

심볼을 포함한 모든 프로퍼티를 확인할 수 있음

 

 

근데 대부분의 라이브러리, 내장함수들은 이러한 메소드들을 사용하지 않으니깐

걱정말고 <유일한 식별자> 가 필요할 때 Symbol 을 사용하자

 

 

5-5.

사용해보자

 

심볼 사용하지 않고 속성 추가할 경우

1000줄 아래에 있어서 있는 줄도 몰랐던 for ... in 문에서 걸려

사용자에게 저런 말도 안되는 메시지를 보여주게 되었다

 

이럴 때 심볼을 사용해주면

for ... in 문에서 걸리지 않고 통과하기 때문에 숨길 수 있음

 

내가 원하는 작업(이름만 확인해보기)을 수행하면서도,

다른 개발자가 만들어놓은 코드의 기능을 방해하거나 방해받지 않을 수 있다 

 

이렇게 <유일한 식별자>는 다른사람 코드에 영향을 끼치지 않으니까

저 객체에 이미 showName 이라는 프로퍼티가 사용되고 있는지,

덮어 씌우지는 않을지 걱정하지 않고 막 사용할 수 있다 오예

 


 

 

6. 숫자랑 수학...

 

 

6-1. toString()

10진수를 -> 2진수 / 16진수로 변경

let num = 10;

num.toString();  // "10"
num.toString(2);  // "1010" (2진수)

let num2 = 255;

num2.toString(16);  // "ff" (16진수)

 

 

 

6-2. Math

자바스크립트에는 수학과 관련된 프로퍼티와 메서드들을 갖고있는 Math 라는 객체가 있음

 

대표적인 프로퍼티 예

Math.PI;  // 3.141592653589793

 

Math.ceil() : 올림

let num1 = 5.1;
let num2 = 5.7;

Math.ceil(num1);  // 6
Math.ceil(num2);  // 6

 

Math.floor() : 내림

let num1 = 5.1;
let num2 = 5.7;

Math.floor(num1);  // 5
Math.floor(num2);  // 5

 

Math.round() : 반올림

let num1 = 5.1;
let num2 = 5.7;

Math.round(num1);  // 5
Math.round(num2);  // 6

 

toFixed() : 소수점 자릿수

괄호 안에 표현하고 싶은 수수점 자릿수를 적어주면 된다

let myRate = 30.1234;

myRage.toFixed(2);  // "30.12"
myRage.toFixed(0);  // "30"  // 정수부분만 남게됨
myRage.toFixed(6);  // "30.123400"  // 0으로 채워줌

to Fixed 는 근데 주의해야할 점이 있다. 

바로 "문자열"을 반환한다는 점.

myRage.toFixed(2);  // "30.12"
Number(myRage.toFixed(2));  // 30.12

필요하다면 Number() 를 이용해 숫자로 바꿔주면 된다

입력받은 값 숫자 변환은 파이썬 int() 로 많이 해봤지!

 

 

 

6-3. isNaN()

 

NaN(Not a Number) 인지 아닌지 판단해줌

isNaN() 만이 NaN 인지 아닌지 판단할 수 있다

isNaN(x)  // true
isNaN(3)  // false

 

NaN 은 자기자신과도 같지 않다고 판단한다. 이상해

x == NaN  // false
x === NaN  // false
NaN == NaN  // false

 

 

 

6-4. parselnt()

 

문자열을 숫자로 바꿔준다

Number()와 다른점 : 문자형이 혼용되어 있어도 동작을 한다

let margin = "10px";

parseInt(margin);  // 10
Number(margin);  // NaN

 

근데 변환할 수 있는 부분까지만 읽은 다음에 바로 반환을 해버리기 때문에

만약 문자형이 젤 앞에 있으면 바로 NaN 을 반환하게 된다

let redColor = "f3";

parseInt(redColor);  // NaN

 

이 때 사용할 수 있는 방법

두 번째 인수를 받아서 진수를 지정할 수 있다

let redColor = "f3";

parseInt(redColor, 16);  // 243

parseInt("11", 2);  // 3

 

 

 

6-5. parseFloat()

 

parseInt() 랑 동일하게 동작하지만, 부동소수점을 반환함

let padding = "18.5%";

parseInt(padding);  // 18
parseFloat(padding);  // 18.5

 

 

 

6-6. Math.random()

 

0~1 사이의 무작위 숫자를 생성한다.

Math.random()  // 0.86452564852

 

1~100 까지 임의의 숫자를 뽑고 싶다면?

Math.floor(Math.random() * 100) + 1

- 100 곱해서 정수부분이 0 부터 99까지 중 하나인 수 생성

- floor() : 내림 으로 소수점 버려

- 그다음 1 더하면 1 부터 100까지가 되겠지

 

 

 

6-7. Math.max() / Math.min()

 

괄호안의 인수들 중 최대값 / 최소값 구하기

Math.max(1,3,-1,5,10,9,2.24);  // 10
Math.min(1,3,-1,5,10,9,2.24);  // -1

 

 

6-8. Math.abs()

 

절대값 구해줌

abs: absolute 의 약자인듯

Math.abs(-1);  // 1

 

 

6-9. Math.pow()

 

n의 m 제곱 값

pow: power 의 약자

Math.pow(2, 10);  // 1024

 

 

6-10. Math.sqrt()

 

제곱근 구해줌

sqrt: square 제곱 root 근의 약자

Math.sqrt(16);  // 4

 


 

7. String

 

7-1.

문자열을 표현하는 방법은 3가지

 

- 작은따옴표 '

- 큰따옴표 "

- 백틱 `

 

딱히 규칙은 없고 알아서 쓰면 됨

근데 각각 사용하기 유리할때가 있음

let html = '<div class="box_title">제목</div>'  // html
let desc = "It's 3 o'clock."  // 영어
let add = `2 더하기 3은 ${2+3} 이다`  // 변수,표현식 넣을때

 

그리고 백틱의 유용한 기능 하나 더 있음

바로 여러줄 표현이 가능하다는 것

let desc = `티라노는 공룡왕이 아니다
스피노사우르스가 더 쎄다.`;

// 따옴표로 줄바꿈은 \n 입력해줘야함 그리고 엔터 치면 오류남
let desc = "티라노는 공룡왕이 아니다\n스피노사우르스가 더 쎄다.";

 

 

7-2.

 

str.length

문자열도 배열처럼 길이 구할 수 있다

let desc = "스피노사우르스.";

desc.length  // 8

 

str[]

특정 위치에 접근도 가능

let desc = "스피노사우르스.";

desc[3]  // "사"

 

 

7-3.

 

str.toUpperCase()

모든 영문을 대문자로 바꿔줌

let desc = "Hi, Kinggoddino";

desc.toUpperCase();  // "HI, KINGGODDINO"

 

str.toLowerCase()

모든 영문을 소문자로 바꿔줌

let desc = "Hi, Kinggoddino";

desc.toLowerCase();  // "hi, kinggoddino"

 

 

7-4.

 

str.indexOf()

문자열을 인수로 받아서 몇번째에 위치하고 있는지 알려줌

젤 처음으로 발견한 위치를 알려주고, 없을 경우 -1 반환

let desc = "Hi, Spino. Nice to meet you.";

desc.indexOf("to");  // 16
desc.indexOf("dinosaur");  // -1

 

주의할점은 0부터 센다는 점이다

if문은 0일때 false 를 반환하기 때문에,

if문에서 사용 시 -1보다 크다 라는 조건을 줘야 한다.

if (desc.indexOf("Hi") > -1) {
  console.log("Hi가 표함된 문장입니다");
}

아래 7-9 예시에서 확인하기

 

 

 

7-5.

 

str.slice(n, m)

특정 범위(n부터 m 까지)의 문자열만 반환한다

 

n

- 시작점

m

- 안적으면: 문자열 끝까지를 의미

- 양수면: 그 숫자 전까지를 의미(포함안하고)

- 음수면: 끝에서부터 셈

let desc = "abcdefg";

desc.slice(2)  // "cdefg"
desc.slice(0,5)  // "abcde"
desc.slice(2,-2)  // "cde"

 

 

str.substring(n, m)

특정 범위(n과 m 사이)의 문자열만 반환한다

'사이' 의 의미이기 때문에 n과 m을 바꿔도 동작함

음수를 허용하지 않음. 음수는 0으로 인식한다.

let desc = "abcdefg";

desc.substring(2,5)  // "cde"
desc.substring(5,2)  // "cde"

 

 

str.substr(n, m)

특정 개수(n부터 시작해서 m개)의 문자열만 반환한다

let desc = "abcdefg";

desc.substr(2,4)  // "cdef"
desc.substr(-4,2)  // "de"

근데 왜 얘는 거꾸로 셀 때 0부터 안세고 -1부터 세지...?

>>> 월요일에 물어보자

 

 

 

7-6. 

 

str.trim()

앞 뒤 공백을 제거함

사용자로부터 뭔가를 입력받을 때 사용함

let desc = "  coding    ";

desc.trim();  // "coding"

 

 

 

7-7.

 

str.repeat(n)

n 번 반복함

let dino = "Spino!";

dino.repeat(3);  // "Spino!Spino!Spino!"

 

 

7-8. 

 

문자열도 비교 가능

1 < 3  // true
"a" < "c"  // true

 

codePointAt()

 

우와!!!!!! 이걸로 아스키코드표에서 십진법에 해당하는 수 얻을 수 있다!!!!

(fromCodePoint() 이건 반대!)

아니야 신나지마

제발 아스키코드 숫자 외우지마 필요없어

 

그냥 a 보다 z 가 크다, 대문자보다 소문자가 크다 정도만 알고 넘어가자

 

 

 

7-9. 예시

 

slice로 원하는 부분만 출력

 

금칙어 걸러내기

indexOf 가 0부터 세기 때문에 if문에서 사용하려면 -1 을 적용해줘야 한다

-1 적용 안했을 때
-1 적용했을 때

indexOf 말고 includes 활용할 수도 있다

 


 

8. Array 메서드

 

8-1. 이전에 배웠던거

 

- push(): 뒤에 삽입

- pop(): 뒤에 삭제

- unshift(): 앞에 삽입

- shift(): 앞에 삭제

 

 

8-2.

arr.splice(n,m,x)

 

- 배열에서 특정 요소를 지운다

n: 시작점

m: 개수

 

- 그리고 그 자리에 추가도 할 수 있다

x: 추가할 요소

 

let arr = [1,2,3,4,5];
arr.splice(1,2);  // 지우기만 해보기 (n,m)
console.log(arr);  // [1,4,5]

let arr = [1,2,3,4,5];
arr.splice(1,3,100,200);  // 지우고 그자리에 추가 (n,m,x)
console.log(arr);  // [1,100,200,5]

let arr = ["쥬라기","보고싶다"];
arr.splice(1,0,"월드","영화");  // 삭제없이 추가 (m=0)
console.log(arr);  // ["쥬라기","월드","영화","보고싶다]

 

어 근데 특이한 점은 

arr.splice() 는 삭제된 요소를 반환한다.

let arr = [1,2,3,4,5];
let result = arr.splice(1,2);

console.log(arr);  // [1,4,5] 삭제된 결과
console.log(result);  // [2,3] 삭제된 값

 

 

8-3.

arr.slice(n,m)

n 부터 m 까지 반환한다

n

- 시작점

m

- 포함하지 않고 바로 앞까지를 의미

- 안쓰면 끝까지를 의미

let arr = [1,2,3,4,5];

arr.slice(1,4);  // [2,3,4]

 

 

8-4.

arr.concat(arr2, arr3 ...)

인자로 주어진 배열 or 값들을 기존 배열에 합쳐서 새 배열 반환

let arr = [1,2];
arr.concat([3,4]);  // [1,2,3,4]
arr.concat([3,4],[5,6]);  // [1,2,3,4,5,6]
arr.concat([3,4],5,6);  // [1,2,3,4,5,6]

 

 

8-5.

arr.forEach(fn)

배열 반복

 

forEach는 함수를 인수로 받음. 세개의 매개변수

- item: 해당 요소

- index: 인덱스

- arr: 해당 배열 자체를 의미. 보통 사용잘안함

 

 

8-6. 

arr.indexOf()

arr.lastIndexOf()

인수에 대해 첫번째로 발견한 인덱스값을 찾아줌

let arr = [1,2,3,4,5,6,7,8];

arr.indexOf(3);  // 2
arr.indexOf(3,3);  // 7 두번째 인수는 시작위치를 의미

arr.lastIndextOf(3);  // 7 끝에서부터 탐색

 

 

8-7.

arr.includes()

배열 내에 인수를 포함하고 있는지 확인

let arr = [1,2,3];

arr.includes(2);  // true
arr.includes(8);  // false

 

 

8-8.

arr.find(fn)

arr.findIndex(fn)

인덱스오브랑 비슷하긴한데 좀더 복잡한 조건으로도 찾을수 있도록

함수를 연결할 수 있다. ex) 짝수 찾아라, 성인 찾아라

 

find()

- 첫번째 true 값만 반환하고 끝

- 없으면 undefined 를 반환한다

 

findIndex()

- 해당 인덱스를 반환한다

- 없으면 -1을 반환한다

 

언제 쓰냐

복잡한 조건으로 찾을 수 있도록 함수 연결해서 사용 (짝수찾기)

 

객체가 들어있는 배열인 경우 indexOf 사용하기 힘드니 find 사용

find() 사용했을 경우
findIndex() 사용했을 경우

근데 

Brachio도 19살보다 어린데 안찾아준다.

젤 처음으로 true 가 나오는 값만 반환한 다음에 끝내버리기 때문이다

매몰차

 

 

만족하는 모든 값들을 찾아내고 싶다면

filter() 를 사용해야 한다.

 

 

8-9.

arr.filter(fn)

만족하는 모든 요소를 배열로 반환

굳굳

19살보다 어린 공룡들이 전부 반환되었다

 

 

8-10.

arr.reverse()

역순으로 정렬

최신에 등록된 순으로 정렬이 필요할 때 사용할 듯

let arr = [1,2,3,4,5];

arr.reverse();  // [5,4,3,2,1]

 

 

 

8-11.

arr.map(fn)

함수를 받아 특정 기능을  시행하고 새로운 배열을 반환

 

 

 

8-12.

 

arr.join() : 배열 → 문자열

배열을 합쳐서 문자열로 만든다.

인수로 전달받은 문자를 기준으로 결합해준다.

만약 아무것도 전달하지 않으면 쉼표(,)를 기준으로 결합한다.

 

arr.split() : 문자열 → 배열

반대로 문자열을 분리해서 배열로 만든다.

인수로 전달받은 문자를 기준으로 분리해준다.

공백을 전달하면 모든 문자를 분리해서 배열의 요소로 넣는다.

 

 

8-13.

 

arr.isArray()

배열인지 아닌지 구분해준다.

typeof() 로 확인하면 둘 다 object 라고 반환해서 구분할 수가 없는데

isArray() 를 써주면 구분 할 수 있다.

 

 

8-14.

 

arr.sort(fn)

배열 재정렬

배열 자체가 변경되니 주의!!!

let arr = [27, 8, 5, 13];

arr.sort();

console.log(arr);  // [13, 27, 5, 8]

뭔가 정렬을 해주긴 하는데 이상하게 해준다.

그 이유는

정렬할 때 요소를 문자열로 취급하기 때문이다.

1과 2로 시작하는 13과 27이 앞쪽으로 정렬됨

 

제대로 정렬을 하고싶다면

정렬 로직을 담은 함수를 sort()의 인수로 전달해줘야한다.

 

근데 너무 어렵다.

그래서 보통은 정렬 함수를 직접 만들기 보다는

 

유용한 기능을 모아놓은 Lodash 라이브러리를 사용한다

 

Lodash를 사용하면

_.sortBy(arr);

숫자든 문자든 원하는 기준으로 정렬해준다.

 

https://lodash.com/

 

Lodash

_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });_.partition([1, 2, 3, 4], n => n % 2);DownloadLodash is released under the MIT license & supports modern environments. Review the build differences & pick one that’s right for you.InstallationIn

lodash.com

지금은 시간이 없으니까 진정하구 다음에 꼭 구경해보자

 

 

 

8-15.

 

arr.reduce()

배열을 돌면서 원하는 작업을 하고 최종값을 반환한다.

인수로 함수를 받는다.

 

- 첫번째 인수: 누적 계산값

- 두번째 인수: 현재값

- return: 계산값

 

먼소린지 모르겠으니까 예시를 보자

 

지금부터 배열의 합을 구해볼건데

일단 forEach 사용해서 구해본다.

let arr = [1,2,3,4,5];  // 합 구하기

let result = 0;
arr.forEach((num) => {
  result += num;
});

console.log(result);  // 15

 

이걸 reduce 로 바꾸면

let arr = [1,2,3,4,5];

const result = arr.reduce((prev, cur) => {
  return prev + cur;  // 누산값 + 현재값
}, 0);  // 초기값 설정 (안써도 됨)

console.log(result);  // 15

 

예시

 

 


 

9. 구조 분해 할당

 

구조 분해 할당(Destructuring assignment)

: 배열이나 객체의 속성을 분해해서 그 값을 변수에 담을 수 있게 하는 표현식

 

9-1.

배열 구조 분해

let [x, y] = [1, 2];

console.log(x);  // 1
console.log(y);  // 2

그냥 보면 먼말인지 안다

let users = ["Spino", "Allo", "Tyranno"];
let [user1, user2, user3] = users;  // 배열을 할당

console.log(user1);  // "Spino"
console.log(user2);  // "Allo"
console.log(user3);  // "Tyranno"

배열을 할당할 수도 있다. 순서대로 넣어주는 거임

let str = "Spino-Allo-Tyranno";
let [user1, user2, user3] = str.split('-');  // split 이용해서 할당

console.log(user1);  // "Spino"
console.log(user2);  // "Allo"
console.log(user3);  // "Tyranno"

split 활용해서도 할당 가능

 

 

9-2.

들어갈 값이 없으면 undefined 가 할당되는데,

이를 방지하기 위해서 디폴트 값을 설정해 줄 수 있다.

let [a,b,c] = [1,2];  // c 에 undefined 할당

let [a=3, b=4, c=5] = [1,2];  // a=1, b=2, c=5

 

 

9-3.

공백을 이용해서 일부 반환값을 무시할 수 있다.

let [user1, , user2] = ["spino", "stego", "allo", "tyranno"];

console.log(user2);  // "allo"

 

 

9-4.

바꿔치기

[a, b] = [b, a];

 

 

여기까지가 배열 구조 분해.

 

아래부터 객체 구조 분해

 

 

9-5. 

객체 구조 분해

let user = {name: "Spino", age: 23};

let {name, age} = user;
let {age, name} = user;  // 이렇게 해도됨

console.log(name);  // "Spino"
console.log(age);  // 23

배열 구조 분해랑 똑같은데

한가지 다른점은 순서를 신경쓸 필요가 없다는 것이다.

순서를 바꿔도 동일하게 동작함.

 

 

9-6.

새로운 변수 이름으로 할당 가능

let user = {name: "Spino", age: 23};

let {name: userName, age: userAge) = user;

console.log(userName);  // "Spino"
console.log(userAge);  // 23

 

 

9-7.

객체도 마찬가지로 기본값 설정 가능

객체로부터 할당받은 값이 undefinded일 때만 디폴트값이 사용됨

let user = {name: "Spino", age: 23}

let {name, age, gender = "male"} = user;

 


 

10. 

나머지 매개변수(Rest parameters)

전개 구문(Spread syntax)

인수가 몇개 들어올 지 모를 때 사용하면 편리하다

파이썬의 애스터리스크같은 느낌인거같다.

 

10-1.

자바스크립트에서 함수에 넘겨주는 인수의 개수에는 제약이 없다

function showName(name){
  console.log(name);
}

showName("Spino");  //  "Spino"
showName("Spino", "Allo");  //  "Spino"
showName();  // undefined

인수의 개수를 정해놓고 함수를 정의하더라도

실제 호출할 때 그 개수를 맞춰줄 필요는 없음 (완전 유연하네)

 

 

함수의 인수를 얻는 방법은 2가지가 있다

- arguments 로 접근

- 나머지 매개변수 쓰기

 

 

10-2.

arguments

- 함수로 넘어온 모든 인수에 접근할 수 있음

- 함수내에서 이용 가능한 지역 변수임

- length 와 index 의 속성을 갖고있기 때문에 배열이라고 오해할 수 있지만

- 사실은 Array 형태의 객체이다

- 그래서 배열의 내장 메서드를 갖고있지 않음(forEach, map 등)

function showName(name){
  console.log(arguments.length);  // 2 받은인수의 개수
  console.log(arguments[0]);  // "Spino"
  console.log(arguments[1]);  // "Allo"
}

showName("Spino", "Allo");

 

 

 

10-3.

나머지 매개변수(Rest parameters)

- 정해지지 않은 개수의 인수를 배열로 나타낼 수 있게 함

- arguments와 달리 배열의 메서드 사용 가능

 

사용 방법

...names

점 세개를 찍고 배열의 이름을 적어줌

function showName(...names){  // names 변수 안에 전달된 인수들이 들어감
  console.log(names);
}

showName();  // [] 전달된 인수가 없으면 undefined가 아니라 빈 배열 반환
showName("Spino");  // ["Spino"]
showName("Spino", "Allo");  // ["Spino", "Allo"]

 

예시

파이썬에서 애스터리스크로 매개변수 개수 제한 없이 받는 그런 느낌이다.

 

reduce 로 바꿔보자

 

일반 변수랑 나머지 매개변수랑 같이 쓸 수도 있다.

앞에 두개는 일반 변수로 받은 다음에, 몇개가 들어올지 모르는 skills 에 대해서는 나머지 매개변수로 받기

 

주의할 점은

나머지 매개변수는 항상 젤 마지막에 있어야함

 

 

10-4.

전개 구문(Spread syntax)

 

배열에서 사용

let arr1 = [1, 2, 3];
let arr2 = [4, 5, 6];

let result = [0, ...arr1, ...arr2, 7, 8, 9];
// [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

배열에 push, splice, concat 하는 귀찮은 작업을 하지 않고 쉽게 할 수 잇다

 

객체에서도 사용 가능

let user = {name:"Spino"}
let spino = {...user, age:30}

console.log(spino)  // {name:"Spino", age:30}

Object.assign() 없이 쉽게 복제할 수 있다

 

 

10-5.

예시

유저에 info 와 skill 을 넣어줄때 전개구문 사용하지 않고, 사용하고 차이점 테스트

전개구문 사용 안했을 때
전개구문 사용했을 때

 

우아 엄청 간단하게 쓸 수 있다!!

 

 


 

'JavaScript' 카테고리의 다른 글

자바스크립트 공부 #3  (2) 2024.10.05
자바스크립트 공부 #1  (0) 2024.10.04