[JS] 프로토타입 간단 정리

[JS] 프로토타입 간단 정리

이채현

자바스크립트는 프로토타입 기반의 언어다.

constructor (생성자)

1
2
3
4
5
6
7
8
9
10
function Person(name, age) {
this.name = name;
this.age = age;
}

class Paerson {
constructor() {

}
}

생성자함수는 프로토타입이 모든 자바스크립트에 들어있듯이 생성자도 모든 자바스크립트에서 확인가능하다.

1
2
3
4
5
const one = new Person('one', 1);
const two = new Person('two', 2);

console.log(one.constructor); // [Function: Person]
console.log(two.constructor.name); // Person

어떠한 생성자로부터 생성되었는지 유추할 수 있다.

instanceof로 식별

object instanceof constructor

proto

브라우저에서 비표준으로 제공했던…

1
array.__proto__ ...로 array의 프로토타입에 접근

자바스크립트의 프로토타입에 직접 접근이 아니라 접근제어자로 접근할 수 있도록 도와주는 것으로 생각하면 됨. ⇒ 하지만 사용하지 않는 것이 좋음

ECMA Script2015부터는 표준화 된

  • getPrototypeOf()
  • setPrototypeOf()

를 사용하는 것을 추천

프로토타입 체인

1
2
3
4
5
6
7
8
9
const animal = {
sayName() {
return 'ANIMAL';
}
}

console.log(animal.sayName()); // ANIMAL
const dog = Object.create(animal);
console.log(dog.sayName()); // ANIMAL

프로토타입 확장 (extends, 상속)

부모 ⇒ 자식 … 상속보단 확장이란 개념이 더 이해하기 쉽다. 부모가 가진 기능보다 자식이 더 많이 가질 수 있기 때문

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// Super Class
function Animal(name, sound) {
this.name = name
this.sound = sound;
}

Animal.prototype.getInfo = function () {
return this.name + '가(이)' + this.sound + '소리를 낸다.';
}

// Sub Class
function Friends(name, sound) {
Animal.call(this, name, sound); // 명시적 바인딩 -> Animal함수의 this를 Friends로 바인딩
}

Friends.prototype = Object.create(Animal.prototype);
Friends.prototype.constructor = Friends;

const dog = new Friends('개', '멍멍');
const cat = new Friends('고양이', '냐옹');

console.log(dog.getInfo()); // 개가(이)멍멍소리를 낸다.
console.log(cat.getInfo()); // 고양이가(이)냐옹소리를 낸다.

-------

dog.contructor.name // Friends

dog instanceof Friends // true
dog instanceof Animal // true
[JS] this 간단 정리

[JS] this 간단 정리

이채현

JavaScript에서 함수의 this 키워드는 다른 언어와 조금 다르게 동작한다.

엄격모드와 비엄격 모드에서도 일부 차이가 있다.

  • this는 scope와 관계가 있다.
  • 객체에도 영향을 준다.
  • this가 어디에 묶여있냐를 아는 것이 코드를 작성하는 시점, 동작하는 시점에 차이가 있을 수 있다.

(함수를 어떻게 호출했는지 상관하지 않고 this값을 설정할 수 있는 bind메서드를 도입했고, ES2015는 스스로의 this 바인딩을 제공하지 않는 화살표 함수 를 추가했습니다.)

암시적 바인딩

암시적인 this 바인딩.. 사용자가 생각하지 않은대로 동작할 수 있다.

전역 공간에서의 this

  • node.js 환경에서의 this는 global
  • 브라우저에서의 this는 window

함수

  • 함수에서의 this는 window ⇒ 전역공간에서의 this와 다르지 않다.

객체 (메서드)

  • this는 호출되는 대상의 객체를 가리키고 있다.
1
2
3
4
5
6
7
8
const obj = {
name: 'obj',
method: function() {
return this.name
}
}

obj.method() // 'obj'

명시적 바인딩

  • call(), bind(), apply()
1
2
3
4
5
6
7
8
9
10
11
12
13
const person = {
name: 'Lee',
sayName: function () {
return this.name + '입니다';
}
}

const zero = {
name: '베이스',
sayName: function () {
return this.name + '입니다';
}
}
  • call()
1
2
3
4
5
function sayFullName(firstName) {
return firstName + this.sayName()
}
const result = sayFullName.call(person, 'Chaehyeon ');
// Chaehyeon Lee입니다.
  • apply()
1
2
3
4
5
6
function sayFullName(firstName) {
return arguments[1] + this.sayName()
}

const result = sayFullName.apply(person, ['Chaehyeon ','채현 ']);
// 채현 Lee입니다.
  • bind()
    • this를 묶어서 사용가능한다.

    • React Class Component에서 사용했다.

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function sayFullName(firstName) {
      return firstName + this.sayName()
      }

      const sayFullNamePerson = sayFullName.bind(person);
      const sayFullNameZero = sayFullName.bind(zero);
      console.log(sayFullNamePerson('Chaehyeon'));

      // ChaehyeonLee입니다
[JS] 스코프 간단 정리

[JS] 스코프 간단 정리

이채현

전역 스코프 (Global)

  • 그냥 가장 바깥쪽
  • 언제 어디서나 접근 가능하기 때문에 재정의가 가능하다 ← 큰 문제
    • 그 결과, 프로그램의 실행 결과 때 내가 만든 변수들의 결과를 예측하기 어려워짐 → 팀 단위로 개발할 때 최악

지역 스코프

함수 스코프

블록 스코프

1
2
3
4
5
6
7
8
9
{
// 블록
}

function func() { // 함수 스코프 블록
}

if (true) { // 블록 스코프 블록
}

전역 객체

브라우저

⇒ window

NodeJS

⇒ Global

// this

  • 브라우저에서 호출하면 window불러옴

호이스팅 (Hoisting)

1
2
3
4
5
6
7
8
9
function foo() {
console.log(hoist); // undefined

var hoist = '호이스팅';

console.log(hoist); // 호이스팅
}

foo();
  • 첫번 째 console.log가 오류나지 않는 이유는

    • 변수 선언을 직접적으로 끌어올림
    • 그래서 위 코드와 아래 코드랑 같다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    function foo() {
    var hoist; // 1. 변수 선언
    console.log(hoist); // undefined // 2. 실행

    hoist = '호이스팅'; // 3. 재할당
    console.log(hoist); // 호이스팅
    }

    foo();

애초부터 var를 안쓰면 된다.

1
2
3
4
5
6
7
8
9
function foo() {
console.log(hoist); // Cannnot access 'hoist' before initialization

let/const hoist = '호이스팅';

console.log(hoist); // 호이스팅
}

foo(); // Cannnot access 'hoist' before initialization
  • 임시적 사각지대 (TDZ)가 생긴다.
  • 내부적으로 호이스팅이 일어나지만, 사용자에게는 보이지 않는것처럼 에러를 준다.

IIFE (즉시 실행 함수 표현)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function func() {

}

func();

==>

(function () {

})();

(function (num) {
console.log(num); // 1
})(1);

함수를 괄호안에 넣고 바로 실행

  • 함수 공간을 완전히 분리할 수 있기 때문에 사용한다.
    • 그래서 let/const가 없을 때에 사람들이 외부에서 접근할 수 없게 블록스코프를 흉내내게 사용했다.
[JS] 자료 다루기

[JS] 자료 다루기

이채현

객체

Object.keys()

  • 객체의 키들이다~~라는 느낌으로 객체의 키들이 배열로 반환된다.
1
2
3
4
5
6
7
8
const object1 = {
a: 'somestring',
b: 42,
c: false
};

console.log(Object.keys(object1));
// expected output: Array ["a", "b", "c"]

Object.values()

  • 객체의 값들이다~~라는 느낌으로 객체의 Value들이 배열로 반환된다.
1
2
3
4
5
6
7
8
const object1 = {
a: 'somestring',
b: 42,
c: false
};

console.log(Object.values(object1));
// expected output: Array ["somestring", 42, false]

Object.entries()

  • 객체를 인자로 받아, key와 value를 쌍으로 가진 배열을 반환한다.
  • for…in와 같은 순서로 주어진 객체 자체의 enumerable 속성을 가짐
    • 인덱스마다 배열을 가져서, 첫번째가 key, 두번째가 value이다.
      • 배열안에 배열
1
2
3
4
5
6
7
8
9
10
11
12
const object1 = {
a: 'somestring',
b: 42
};

for (const [key, value] of Object.entries(object1)) {
console.log(`${key}: ${value}`);
}

// expected output:
// "a: somestring"
// "b: 42"

배열

요소 추가와 제거

  • unshift ⇒ 배열의 앞에 요소 추가

  • push ⇒ 배열의 끝에 요소 추가

  • shift ⇒ 배열의 앞에 요소 제거

  • pop ⇒ 배열의 끝에 요소 제거

  • splice ⇒ 배열의 인덱스를 기반으로 요소 추가 및 제거

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    array.splice(start[, deleteCount[, item1[, item2[, ...]]]])

    const months = ['Jan', 'March', 'April', 'June'];
    months.splice(1, 0, 'Feb');
    // inserts at index 1
    console.log(months);
    // expected output: Array ["Jan", "Feb", "March", "April", "June"]

    months.splice(4, 1, 'May');
    // replaces 1 element at index 4
    console.log(months);
    // expected output: Array ["Jan", "Feb", "March", "April", "May"]

요소 병합

  • concat
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
const array1 = ['a', 'b', 'c'];
const array2 = ['d', 'e', 'f'];
const array3 = array1.concat(array2);

console.log(array3);
// expected output: Array ["a", "b", "c", "d", "e", "f"]

const alpha = ['a', 'b', 'c'];

alpha.concat(1, [2, 3]);
// 결과: ['a', 'b', 'c', 1, 2, 3]

--------

const newArr = [...array1, ...array2];
// ['a', 'b', 'c', 'd', 'e', 'f']

고차 함수로 조작 (내장 메서드)

  • 대표적으로 map, filter, reduce

map

1
2
3
4
5
const langs = ['JS', 'HTML', 'CSS'];

const newLangs = langs.map(lang => lang + ' 언어');
console.log(newLangs);
// [ 'JS 언어', 'HTML 언어', 'CSS 언어' ]

filter

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
const langs = ['JS', 'HTML', 'CSS', 0, 1, 2, 3];

const numbers = langs.filter(lang => {
if (typeof lang === 'number') {
return true;
}
});
console.log(numbers);
// [ 0, 1, 2, 3 ]

const strings = langs.filter(lang => {
if (typeof lang === 'string') {
return lang;
}
})
console.log(strings)
// [ 'JS', 'HTML', 'CSS' ]
const isNumber = function (el) {
if (typeof el === 'number') {
return true;
}
}
const numbers = langs.filter(isNumber);
console.log(numbers)

const isString = (el) => typeof el === 'string';
const strings = langs.filter(isString)
console.log(string)

// [ 0, 1, 2, 3 ]
// [ 'JS', 'HTML', 'CSS' ]

reduce

  • 그전에 전형적인 명령어 프로그래밍 방식
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// argument로 받거나
// 인자에 spread형식으로 받거나...

function sumTotal() {
let temp = 0;
for (let i = 0; i < arguments.length; i++) {
temp = temp + arguments[i];
}
return temp;
}

console.log(sumTotal(1, 2, 3, 4, 5, 6, 7));
// 28
function sumTotal(...numbers) {
let temp = 0;
// reduce((누적값, 현재값){},초기값)
return numbers.reduce((total, current) => total + current, 0);
// 첫번째는 초기값(total(0))+ 인자(1)이 total로 들어가고
// 그 다음 total(1)+인자(cur(2))
}

console.log(sumTotal(1, 2, 3, 4, 5, 6, 7));

요소 정렬

sort

1
2
3
4
5
6
7
8
9
10
const numbers = [4, 2, 5, 1, 3];

const orderNumbers = numbers.sort((a, b) => a - b)
console.log(orderNumbers);
// [ 1, 2, 3, 4, 5 ]

const strings = ['마', '가', '라', '나', '다'];
const orderStrings = strings.sort((a, b) => a.localeCompare(b));
console.log(orderStrings);
//[ '가', '나', '다', '라', '마' ]

값 검색

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const strings = ['마', '가', '라', '나', '다'];

const result = strings.find((string) => string === '나');
console.log(result);
// 나 ///없으면 undefinded

const result = strings.findIndex((string) => string === '나');
console.log(result);
// 3

const result = strings.indexOf('나'); // 왼쪽부터,,, lastIndexOf()
console.log(result);
// 3

const result = strings.includes('나');
console.log(result);
// true
[JS] Object 객체

[JS] Object 객체

이채현

객체 생성

일반적으로 생성 할 수 있는 객체

싱글 리터럴 (Literal) 객체

1
2
3
4
const object = {
property: 'value',
method: function () {},
}

생성자 함수 객체 // PascalCase

1
2
3
4
5
function NewObject(name) {
this.name = name;
}

const newObject = new NewObject(’Lee’);

파스칼 케이스 → 암묵적, 명시적 생성자 함수

Object.Create()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const newObject2 = Object.create(Object.prototype, {
name: {
value: 'lee',
writable: true, // 덮어쓸 수 있는지
enumerable: true, // forin문과 같은 것으로 열거할 수 있는지
configurable: true, // 객체 기술자를 수정할 수 있는지
},
});
// const newObject2 = Object.create(프로토타입, 객체 서술자(기술자));

newObject2.name = 'Kim';

for (const key in newObject2) {
console.log(key);
}

프로퍼티 열거

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
const obj = {
prop1: 'value1',
prop2: 'value2',
prop3: 'value3',
prop4: 'value4',
};

const prop = 'prop';
const prop1 = 'prop1';

obj.prop1 // value1
obj['prop1'] // value1
obj[prop + 1] // value1
obj[prop1] // value1

for (const key in obj) {
console.log(key); // prop1, prop2, prop3, prop4
console.log(obj[key]); // value1, value2, value3, value4
}

체인닝 방지를 위해

블록 스코프 내에 변수가 없으면 그 위로 찾아 간다…

1
2
3
4
5
6
for (const key in obj) {
if (obj.hasOwnProperty(key)) {
console.log(obj[key]); // value1, value2, value3, value4
}
}
// 상속되거나 확장되어 사용 된 객체의 상위에서 꺼내오지 않도록 하는 방어문

프로퍼티 조작

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const person = {
firstName: "Chaehyeon",
location: "Korea",
}

// 추가
person.lastName: "Lee"
// 수정
person.lastName: "lee"
// 삭제
delet person.location;

person; // { firstName: "Chaehyeon", lastName: "lee" }

// const는 재할당을 막는 것... 그래서 가능

프로퍼티 접근자 (getter, setter)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 추가, 수정, 삭제 등을 접근해서 조작할 때 안전하게 하기 위해
const person = {
_firstName: "Chaehyeon",
lastName: "Lee",

get firstName() {
return this._firstName.toUpperCase();
}

set firstName(newFirstName) {
if (typeof newFirstName !== 'string') {
this._firstName = 'undefinedName';

return;
}

this._firstName = newFirstName;
}

get fullName() {
return this._firstName + this.lastName + '입니다'.
}
}

// console.log(person.firstName); // CHAEHYEON
// console.log(person.fullName); // LeeChaehyeon입니다

person.firstName = 12345;
console.log(person.firstName); // UNDEFINDEDNAME

인스턴스

OOP

인스턴스 === 유일한, 고유한 객체?

객체 하나하나가 곧 인스턴스이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const me = {
name: 'chaehyeon',
age: 26,
locaiton: 'korea',
};

const me2 = {
name: 'chaehyeon',
age: 26,
locaiton: 'korea',
};

console.log(me === me2); // false
console.log(me.name === me2.name); // true

// 객체 그 자체를 비교할 때에는 객체의 메모리 주소를 본다.
// 당연히 메모리주소는 다르다

생성자

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
const me = {
name: 'chaehyeon',
age: 26,
locaiton: 'korea',
};

// 객체를 자주 만들고 싶을 때 -> 생성자 함수
function Person(name, age, location) {
this.name = name;
this.age = age;
this.location = location;

this.getName = function () {
return this.name + ' 입니다';
}
}
// 여기서 this는 "생성 될" 인스턴스를 가리킨다.

const me2 = new Person('ChaehyeonLee', 26, 'korea');
// Person { name: 'ChaehyeonLee', age: 26, location: 'korea' }

const you new Person('Kim', 20, 'korea');
// Person { name: 'Kim', age: 20, location: 'korea' }
[JS] DOM 문서 객체 모델

[JS] DOM 문서 객체 모델

이채현

DOM (문서 객체 모델…Document Object Model)

  • HTML ⇒ 문서
  • 문서를 조작하는 언어 ⇒ JavaScript
  • Document Object Model ← JavaScript가 DOM을 통해 HTML을 조작
  • DOM 내부에는 Node: HTML 요소 하나하나 전부를 지칭
    • Node는 Tree형태로 부모노드가 자식노드를, 자식노드가 그 자식노드를…
    • 각 Node에는 수 많은 Properties, Methods…가 존재

결론

  • HTML문서를 JavaScript로 모델링 한 것이 DOM
  • 인터페이스를 하나하나 자르면 단위가 Node이며, Node는 Tree구조로 이루어져있다.

Eg) ’li’ 태그를 뽑아보면 정보가아래처럼 수 많이 담겨있다.

1
2
3
4
5
6
7
8
9
accessKey: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
...

Dom 선택

자바스크립트에서 HTML 특정 Element들을 가져오는 법 (고전적)

  • Document.getElementById() 문서에 특정 id만 가져오고 싶을 때

  • Element.getElementsByClassName()

    클래스 이름으로… 모든 자식의 엘리먼트를 가져온다. → HTML Collection 형태로 가져온다.

  • Document.getElementsByTagName()

    태그 이름으로 가져온다.

자바스크립트에서 HTML 특정 Element들을 가져오는 법 (비교적 최신)

  • Document.querySelector()

    id(.), class(#), tag name 모두에 사용가능, 첫번째로 보이는 것을 가져온다.

  • document.querySelectorAll()

    해당하는 것을 모두 가져온다. (문자열 O) ⇒ NodeList로 가져오기 때문에 Array로 변환해서 사용한다.

  • 그 외 다양한 조합으로 사용가능하다.

    eg) div.note → div태그 내에 note id를 가져온다.

Dom 조작

조작하기 위한 method들도 매우 많기 때문에 MDN문서를 보면서…


  • innerHTML을 통해서 문자열로 컨트롤 가능하다.
[JS] Algorithm - 자주 쓰이는 구문 정리(22.02.06)

[JS] Algorithm - 자주 쓰이는 구문 정리(22.02.06)

이채현

배열 중복값 개수 구하기

reduce()

reduce() 함수는, 배열의 값을 순회하면서 배열의 값을 특정 형태로 누적하는데 사용합니다.

1
2
3
4
5
6
7
8
9
10
const inputNum = [1, 1, 2, 3, 4, 2, 1];

const result1 = inputNum.reduce((obj, t) => (obj[t] = obj[t] ? obj[t] + 1 : 1, obj), {});

const result2 = inputNum.reduce((obj, t) => {
obj[t] = (obj[t] || 0) + 1;
return obj;
}, {});

// { '1': 3, '2': 2, '3': 1, '4': 1 }

forEach()

1
2
3
const cnt = {}
inputNum.forEach((x) => (cnt[x] ? (cnt[x] += 1) : (cnt[x] = 1)));
// { '1': 3, '2': 2, '3': 1, '4': 1 }

forEach의 callback함수를 풀어쓰면 아래와 같다.

1
2
3
4
5
if(cnt[x]) {
cnt[x] = cnt[x] + 1;
} else {
cnt[x] = 1;
}

즉, 처음에 배열의 첫 번째 값인 ‘1’이 들어오면, cnt[x] (cnt.1)은 undefined이다.

cnt[x]가 undefinded이므로 cnt에 key ‘1’를 추가하고 value 1을 세팅해준다.

이후 다시 ‘1’이 들어오면 cnt[1]은 존재하므로, cnt[1]값 1에 1을 더해준다.


배열에 1 ~ N 값 세팅하기

기본 반복문을 이용

1
2
3
4
5
6
7
8
9
10
11
const arr = [];
const N = 10;

for (let i = 1; i <= N; i++) {
arr.push(i);
}

console.log(arr);
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]


ES6의 Array from() and keys() 이용

1
2
3
const arr = Array.from(Array(N).keys());
console.log(arr);
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

Spread를 이용한 방법

1
2
3
const arr = [...Array(10).keys()];
console.log(arr);
// [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 ]

1부터 시작하기 위해 from과 length property 이용

1
2
3
const arr = Array.from({length: 10}, (_, i) => i + 1)
console.log(arr);
// [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

단순 원하는 길이만큼 0으로 채우기

1
2
const array = new Array(10001).fill(0);
console.log(array)
[JS] ES6 - Promise

[JS] ES6 - Promise

이채현

Promises

async

자바스크립트는 순차적으로 처리되는게 아니라 한꺼번에 실행된다. ⇒ 자바스크립트의 비동기성(async)

이벤트 루프에서 비동기적으로 실행시킨다.

Promise

Promise는 비동기 작업이 맞이할 미래의 완료 또는 실패와 그 결과 값을 나타낸다.

내가 아직 모르는 값이랑 같이 일하게 해준다

금방 끝나진 않겠지만 곧 오면 이걸 가지고 작업할 게 표시 해주는 것

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
const promiseTest1 = new Promise((resolve, reject) => {
setTimeout(resolve, 3000, "Test Pass");
});

// setInterval(console.log, 1000, promiseTest1);
promiseTest1.then((value) => console.log(value));

const promiseTest1 = new Promise((resolve, reject) => {
setTimeout(reject, 3000, "Test Fail");
});

// setInterval(console.log, 1000, promiseTest1);
promiseTest1
.then((value) => console.log(value))
.catch((error) => console.log(error));

Chaining Promise

.then().then()…. 할때 리턴 필요

1
2
3
4
5
6
7
8
9
10
const promiseTest2 = new Promise((resolve, reject) => {
resolve(2);
});

promiseTest2
.then((number) => {
console.log(number * 2);
return number * 2;
})
.then((otherNumber) => console.log(otherNumber * 2));

Propmise.all

Promise.all은 주어진 모든 Promise를 실행한 후 진행되는 하나의 Promise를 반환한다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* Promise.all
*/
const p1 = new Promise((resolve) => {
setTimeout(resolve, 5000, "first");
});

const p2 = new Promise((resolve) => {
setTimeout(resolve, 1000, "second");
});

const p3 = new Promise((resolve) => {
setTimeout(resolve, 3000, "third");
});

const motherPromise = Promise.all([p1, p2, p3]);

motherPromise
.then((values) => console.log(values))
.catch((err) => console.log(err));

// 모든 프로미스가 resolve 해야지 출력
// 5초후 마지막 first 끝나야 최종출력
// 중간에 reject 뜨면 바로 중단

Promise.race

기본적으로 promise all이랑 같지만 하나만 resolve 되거나 reject하면 된다. 가장 빨리 리턴 되는 걸로 결정, 부모프로미스를 차지하고 그 값 하나 리턴함

1
2
3
4
5
6
7
8
9
10
/**
* Promise.race
*/
const motherPromise2 = Promise.race([p1, p2, p3]);

motherPromise2
.then((values) => console.log(values))
.catch((err) => console.log(err));

// second

finally

뭘하든 마지막에 실행된다. 보통 작업이 다 끝나고 로딩 끝낼 때 쓴다.

1
2
3
4
5
6
7
8
/**
* Finally
*/
const p1 = new Promise((resolve) => {
setTimeout(resolve, 3000, "first");
})
.then((value) => console.log(value))
.finally(() => console.log("I'm done"));
[JS] ES6 - For

[JS] ES6 - For

이채현

For

forEach

1
2
3
4
5
6
7
8
9
const friends = ["me", "you", "nico"];

const addHeart = (current, index, array ) => ( console.log(current, index, array));

friends.forEach(addHeart);
// 파라미터 첫번째로 값을 주고 두번째로 인덱스를 주고 세번째로 현재 배열을 준다
// me 0 ["me", "you", "nico"]
// you 1 ["me", "you", "nico"]
// nico 2 ["me", "you", "nico"]

for…of

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
for (const friend of friends) {
// 장점 1) const, let 뭐로 할건지 결정가능, forEach에서는 안됨
console.log(friend); // 모두다 출력됨
}

for (const char of "strings") {
console.log(char); // s t r i n g s 출력
}
// 장점 2) iterable한 모든것에서 작동한다

for (const friend of friends) {
if (friend === "steve") {
break;
} else {
console.log(char); // "me", "you", "nico" 이렇게만 출력
}
}
// 장점 3) 루프를 멈출수가있음!, 최고장점
[JS] ES6 - Rest and Spread

[JS] ES6 - Rest and Spread

이채현

Rest and Spread

Spread

기본적으로 변수를 가져와 풀어 해쳐 전개해놓는 것.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Spread
*/
const friends = [1, 2, 3, 4];

console.log(friends); // [1, 2, 3, 4]
console.log(...friends); // 1 2 3 4

const family = ["a", "b", "c"];
console.log(friends + family); // 1,2,3,4a,b,c
console.log([friends, family]); // [ [ 1, 2, 3, 4 ], [ 'a', 'b', 'c' ] ]
console.log([...friends, ...family]); // [ 1, 2, 3, 4, 'a', 'b', 'c' ]
// spread를 통해 모든 요소를 담고 있는 하나의 object를 얻을 수 있다.
// array.push()를 이용하지 않고 값을 추가하여 새로운 객체를 만든다.
const newFriends = [...friends, 5, 6, 7];
console.log(newFriends); // [ 1, 2, 3, 4, 5, 6, 7]

const admin = {
username: "admin",
};
console.log({ ...admin, password: 123 }); // { username: 'admin', password: 123 }
// 조건식
// lastName을 입력받았을 때 값이 있을 때만 객체에 넣어주기
const lastName = prompt("Last name: ");
const person = {
username: "person",
age: 24,
...(lastName !== "" && { lastName }), // spread로 전개하려면 데이터가 object여야하므로, 중괄호로 감싸줌
// lastName: lastName !== "" ? lastName : undefined,
};
console.log(person);

Rest Parameters

끝없는 인자를 받아 볼때 유용하게 이용할 수있다

spread는 죄다 펼쳐 확대시키는 것이고, ****rest는 하나에 담아서 축소시키는것

어디에 들어가느냐에 따라 spread와 rest(parameter부분에 들어가면 )로 갈릴수있음

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const infiniteArge = (...kimchi) => console.log(kimchi);

infiniteArge("1", 2, true, "lalala", [1, 2, 3, 4]);
// 전부 배열에 넣어서 출력된다.

const bestFriends = (firstPotato, ...potatos) => {
console.log(`he is ${firstPotato}`);
console.log(potatos);
}

bestFriends("nico", "lynn", "steve", "flynn");
// he is nico
// ["lynn", "steve", "flynn"]
// 이렇게 출력된다

Rest + Spread + Destructure Magic

object를 지우거나 정리할 때 유용하다

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const user = {
name :"nico",
age:24,
password : 12345
};

const killPassword = ({password, ...rest}) => rest; // destructure + rest
// destructuring을 통해 user의 password를 가져오고, 나머지를 rest에 저장

const cleanUser = killPassword(user)
console.log(cleanUser) // {name:"nico", age:24} 출력한다

const setCountry = ({ country = "KR", ...rest }) => ({ country, ...rest });
// default 설정 + rest + spread

console.log(setCountry(user));

// {country : "KR", name :"nico", age:24, password : 12345} 출력