ES6_JavaScript

김정훈·2023년 8월 9일
0
post-thumbnail

Es6 this

그냥 function 사용할 때에만 this사용(이 때 this는 window)
ArrowFunction에서 사용하기는 애매하다.

// Function에서의 this - window를 가리킨다.
function test(){
  	console.log(this);
}

document.getElementById('win').addEvenetListener('click', function(e){
  let test = [1, 2, 3];
  test.forEach(function(a){
    console.log(this)
  });
})

// Object에서의 this
let obj = {
  data: 'Kim',
  test : function(){
    console.log(this)
  }
}
// → this : 이 함수를 가지고 있는 obj을 뜻한다.

// EventListener의 this
document.getElementById('test').addEventListener('click', function(e){
  console.log(this); // e.currentTarget을 가리킨다.
})

//arrowFunction에서의 this
let arrow = {
  name : ['a','b','c'],
  test : function(){
    console.log(this);
    arrow.name.forEach(()=>{
      console.log(this)
    })
  }
}
// → arrowFunction안의 this는 외부 this값을 그대로 사용한다.(상속받아 사용)
// 여기에서 this 결국 arrow을 가리킨다.

Es6 ArrowFunction

함수를 만드는 경우
코드들을 기능으로 묶고 싶을 때 사용
입출력 기계를 만들고 싶을 때 사용

ArrowFunction 장점
입출력 기계를 만들때 보기 쉬움
파라미터가 1개인 경우 소괄호 생략가능
코드가 한줄이면 중괄호 생략가능

[1,2,3,4].forEach(a => console.log(a));

document.getElementById('test').addEventListener('click', (e) =>{
  e.currentTarget;
});

Es6 template literals

`(백틱) 을 사용하는 표기법이다.

let some = `test`
let article = `반갑다 ${some} 나는 프론트엔드 개발자`;
// 다음과 같이 변수를 넣어서 사용이 가능하다.

function divider(param1, param2){
  console.log(param1);
  console.log(param2);
}
divder`안녕하세요 ${some} 나는 프론트엔드 개발자`
/*
여기서 param2는 변수인 some을 가리킨다.
나누는 기준은 중괄호 이므로,
출력값은
["반갑습니다","나는 프론트엔드 개발자"] Array화 시켜준다.
이렇게 나누어서 나온다.
**/

변수 Hoisting

console.log(age); // undefined
var age = 30;
console.log(age); // 30

1번째 출력값이 null이 아닌 undefined가 뜨는 이유는
JavaScripts는 위의 코드를

var age;
console.log(age);
age=30;
console.log(age);

다음과 같이 동작한다. 이것이 변수 Hoisting이다.
하지만 let, const를 이용하여 코드를 작성하면 다음과 같은 Hoisting현상은 고려하지 않아도 될 것이다.


Es6 spread operator

대괄호, 중괄호, 소괄호 안에서만 사용한다.

let arr = ['12', '34'];
console.log(...arr); // 12 34 이렇게 출력한다.

let test = 'hello';
console.log(...test); // h e l l o 이렇게 출력한다.

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

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

let o1 = {a:1, b:2};
let o2 = {...o1, a:2}; // 중복이 있는 경우 뒤의 값이 적용된다. 즉 a:2, b:2 가 출력된다.

Optional Chainning

let user = {
  name: 'kim',
  age: 20
}
console.log(user?.age);
// ?. : 왼쪽이 있으면 오른쪽 부분 실행 
            
// 중첩된 오브젝트
let user{
	name: 'kim',
    age: {value : 20}
};
console.log(user.age?.value);
            
// → 사실상 중첩된 부분이 아니면 사용하지 않는다. 다음과 같은 경우에는 에러를 일으키지 않고 그냥 undefined해준다.
let user = {
  name: 'kim'
}
console.log(user?.age);

RestParameter

함수안에 들어온 파라미터를 전부 담은 array를 출력한다.
rest파라미터는 가장 뒤에 써야한다.

function test(...rests){
	console.log(rests)
}
test(1,2,3,4,5,6,7)
// console.log 출력값 [1, 2, 3, 4, 5, 6, 7]

function test2(a, b, ...rests2){
  console.log(rests2)
}
test2(1,2,3,4,5,6,7)
// console.log 출력값 [3, 4, 5, 6, 7]

PrimitiveDataType

변수에 값이 그대로 저장된다.

let a = 1234;

ReferenceType

변수에 reference가 저장된다.(저기에 저장되어 있다 가리키는 느낌)
Array, Object는 변수에 값이 저장되지 않는다.
(Array, Object는 함부로 복사X)

let b = [1,2,3,4]

요상한 ReferencType

let n = { name: '김' }
function change(obj){
  obj.name = 'Park';
}
change(n); // name은? Park

let n = { name: '김'}
function change(obj){
  obj = { name : 'Park'}
}
change(n); // name은? 김
/*
→ 이유는 : 파라미터는 변수생성+할당과 똑같다.
사실상 change(n)은
change(let obj=n)이랑 똑같다.
*/

이 그림과 같이 동작하므로 사실상 위 코드에서는 아예 새로운 객체를 생성한다.

어쩌면 TMI
JavaScript에서 객체는 참조 타입이므로 객체가 전달될 때는 실제로 객체의 주소가 전달되며,
함수 내부에서 객체를 수정하면 원본 객체도 함께 변경됩니다.
그러나 함수 내부에서 obj에 새로운 객체를 할당하는 경우, 이전에 전달된 객체의 주소와는 다른 새로운 주소를 가진 객체가 생성되며, 이 객체는 함수 내부에서만 존재합니다.
이는 함수 외부에서 사용되는 n 변수와는 별개의 객체입니다.


Constructor

Object를 마구 복사하고 싶을 때 사용한다.

function Machine(name, age){
	this.name=name;
  	this.age =age;
  	this.sayHi = function(){
      console.log('안녕하세요'+this.name+'입니다.')
    }
}

let some = new Machine('Tester', 20);
// this가 가리키는 것 : 새로 생성되는 오브젝트(Instance)

ProtoType

Prototype은 유전자

function Machine(name, age){
	this.name=name;
  	this.age =age;
  	this.sayHi = function(){
      console.log('안녕하세요'+this.name+'입니다.')
    }
}

Machine.prototype.gender='남';
// 이렇게 하면 부모로부터 생성된 자식들은 모두 .gender을 사용가능

/*
Machine을 만들면 prototype이라는 공간이 자동으로 생긴다.
*/

ProtoType 동작원리

// 두 가지 변수는 똑같은 역할을 한다.
let arr = [1, 2, 3];
let arr = new Array(1,2,3);
arr.sort();

arr에 sort()가 있는가? X
그럼 arr부모의 유전자에 sort()가 있는가? O
그러면 사용한다.

Prototype은 함수에만 몰래 생성된다.

나의 부모Prototype을 알고 싶다면

.__proto__

// __proto__ 을 이용해 부모 강제 등록하기 , 잘 사용하진 않는다.
let a = { name: 'Kim' };
let ab = {};
ab.__proto__ = a;
console.log(ab.name); // Kim이 나온다.

Es5로 상속구현

Object.create();

let a = { name: 'Kim', age: 50};

let ab = Object.create(a);
// Prototype을 a로 해주세요
ab.age=20;

let c = Object.create(ab);
c.name='Kim2'

Es6로 상속구현

class a{
  constructor(){
    this.name='Kim';
    this.sayHi=function(){console.log('hello')} // b에게도 함수가 추가됨
  }
  sayHi(){ // a.prototype에 추가됨
    console.log('hello')
  }
}

let b = new a();

// 두 코드 모두 부모Prototype을 찾아주는 역할
b.__proto__;
Object.getPrototypeOf(b);

extends, super

extends는 복사+상속

class a {
  constructor(name){
    this.first = 'Kim';
    this.last = name;
  }
}

let aTest = new a('Test');

// extends해서 만든 class는 this를 그냥 못 쓴다.
class b extends a{
	constructor(name){
      super(name); // 물려받는 class(a class)의 constructor라는 뜻이다.
      this.age=30;
    }
}

let bc = new b('Tester2');

Getter, Setter

let person = {
  name: 'Park',
  age: 30,
  set nextAge(){
    return this.age+1
  },
  set setAge(age2){
    this.age = parseInt(age2);
  }
}

person.setAge = '20';
person.nextAge;

Es6-Destructing문법

비구조화 할당
: 배열이나 객체에서 값을 추출하여 변수로 할당하는 방법을 제공

let [a,b,c] = [1,2,3]
// let a = 1, let b = 2, let c = 3
let [d, e, f=10] = [4,5]

// 배열에서 비구조화 할당
const numbers = [1, 2, 3, 4, 5];

const [a,b, ...rest] = numbers;
// a=1 ,b=2, rest =[3,4,5]

// 객체 비구조화 할당
let name = 'Kim'
let age = 29;
let obj = {name, age}
// let obj={name:name, age:age}

// 비구조화 할당 사용 전
let obj2 = {name: "Park", age: 30}
let name2 = obj2.name;
let age2 = obj2.age;

// 비구조화 할당 사용 후 : 담을 변수랑 객체의 Key값이 동일해야 한다.
let {name,age} = {name: "Park", age:30}
// 변수의 명을 바꾸고 싶다면 name: callSign 같은 방식으로 수정할 수 있다.
let {name: callSign, age=20} = {name:"Park"} 

동기/비동기처리, 콜백함수

동기
: 동기적인 코드 실행은 순차적으로 진행되는 것을 의미.
코드는 위에서 아래로 순서대로 실행되며 특정 작업이 끝날 때까지 다음 작업으로 넘어가지 않는다.
동기 코드의 실행이 끝나야만 다음 코드가 실행된다.

비동기
: 비동기적인 코드 실행은 순서에 구애받지 않고, 병렬적으로 여러 작업을 동시에 처리할 수 있다.
비동기 작업은 백그라운드에서 동작하며, 작업이 완료되면 해당 작업의 결과를 콜백 함수나 프로미스를 통해 알려준다.

콜백 함수
: 콜백 함수는 비동기 작업의 결과를 처리하기 위해 사용되는 함수.
비동기 작업이 완료되면 해당 작업의 결과를 인자로 받아와서 실행된다. 콜백 함순는 다른 함수의 인자로 전달되며, 해당 함수가 작업을 완료한 뒤 호출됨.

Promise

: Promise는 성공/실패 판정 기계이다.
비동기 작업을 좀 더 효율적으로 다룰 수 있도록 해준다.
비동기 작업이 완료되었거나, 실패했을 때 처리해야 하는 작업을 구조화하고 관리하는데 사용한다.

3가지 상태가 있다.
pending:대기 - 초기 상태로, 비동기 작업이 아직 완료되지 않은 상태.
Fullfilled(resolved):성공 - 비동기 작업이 성공적으로 완료되어 결과 값을 반환한 상태. → then 실행
rejected:실패 - 비동기 작업이 실패하거나 오류가 발생한 상태. → catch 실행

Promise는 여러 개의 비동기 작업을 순차적 또는 병렬로 처리하고, 콜백 지옥을 방지하는 데 도움을 준다.
널리 사용되고 있는 비동기 코드 작성 패턴 중 하나.

let promise = new Promise(function(success, fail){
	setTimeout(function(){
      success();
    },1000);
});

promise.then(function(){
  console.log("Success");
}).catch(function(){
  console.log("Fail");
})

Async Await

asyncfunction 앞에 붙이면 함수 실행 후에 Promise오브젝트가 남는다.

async function plus(){
  1+1;
}
plus().then(function(){
  console.log("성공이다")
})

async function 안에서 쓰는 await
then 대신 사용가능하다.
: await은 실패 판정시 에러가 나고 멈춘다.
try...catch 같이 써줘야 한다.

asyn function sample(){
  let test = new Promise(function(성공,실패){
    let hardTest=1+1;
    성공();
  });
  
  try{
  	let result = await test;     
    // test끝날 때 까지 기다려.
    console.log(result);
  }catch{
    console.log("연산이 실패했나보군");
  }
}

버튼을 클릭하면 성공을 호출하는 Async Await을 만들어보자.

<button id="button">TestButton</button>

<script>
async function buttonTest(){
  	let promise = new Promise(function(성공,실패){
      document.getElementById('button').addEventListener('click', function(){
        성공('클릭성공');
      })
    });
  
  let result = await promise;
  console.log(result);
}

buttonTest();

Map, Set 자료형

Map: 자료의 연관성을 표현하기 위해 사용하는 자료형
Object 자료형은 자료 이름으로 글자만 가능하다.
Map은 모든 자료형 가능

// Map
let person = new Map();
person.set('name', "Kim");
person.set('age',30);

// 한번에 자료를 집어넣고 싶을 때
let person = new Map([
	['name', 'Kim'],
  	['age', 50]
])

person.get('name'); // Kim
person.delete('name'); // 삭제됨
person.size // 자료가 얼마나 저장되어있는지 가르쳐줌

// 반복문으로 Map의 key값 뽑기
for (let key of person.keys()){
  console.log(key);
}

Set: 중복자료를 허용하지 않는 Array와 비슷한 자료형

let attendance = new Set(['john', 'tom','andy','tom']); // {john, tom, andy}

attendance.add('hoon');
attendance.delete('hoon');
attendance.has('john') // boolean 값 출력
attendance.size

// test을 중복제거하여 array로 만드는 과정
let test = [1,2,3,4]
let test2 = new Set([1,2,3,4]);

test = [...test2];

웹브라우저 동작원리(With. Stack Queue)

:JavaScript는 보통 single threaded 언어라고 한다.

Stack, Queue

: Stack,Queue을 바쁘게 하면 사이트가 버벅인다.
→ 어려운 연산은 자바스크립트로 시키면 안 된다.

서버에 요청코드, 이벤트리스너, setTimeout 같은 처리가 오래 걸리는 코드들은 대기실 같은 곳에 놔두고 다른 코드들을 먼저 실행한다.

대기실에서 setTimeout 1초가 지낫다.
그러면 또 다른 대기실인 Queue로 들어간다.
Stack이 비어있을 때 하니씩 차례대로 올라간다.

profile
WebDeveloper

1개의 댓글

comment-user-thumbnail
2023년 8월 9일

잘 읽었습니다. 좋은 정보 감사드립니다.

답글 달기