JS ES6 문법 한눈에 보기
23/01/12 수업
1. let과 const
* let
- let변수는 중복선언이 불가능하다.
- let변수의 유효범위는 {}블록이다. (자바의 변수 범위와 같다고 생각하면 된다.)
//let변수는 같은 블록에서 내에서 중복이 불가능하다.
let y = 1;
// let y = 100; //에러
//let변수의 유효범위는 {}블록이다
let z = 10;
if(true) {
let z = 100;
console.log(z); //100
}
console.log(z); //10
*확인
<body>
<ul class="list">
<li>목록1</li>
<li>목록2</li>
<li>목록3</li>
<li>목록4</li>
</ul>
<script>
//이렇게 사용하는 법 기억해둬야 함.
var lis = document.querySelectorAll(".list li");
//var는 함수 스코프
for(var i = 0; i<lis.length; i++){
(function(x){ //즉시 실행 함수
lis[x].onclick = function(){
console.log(x);
}
})(i);
}
// let lis = document.querySelectorAll(".list li");
// for(let i = 0; i < lis.length; i++){
// lis[i].onclick = function(){
// console.log(i);
// }
// }
</script>
<script>
let x = 1;
//let x =1 //중복 선언 x
if(true){
let x = 10;
console.log(x); //10
}
console.log(x); //1
</script>
</body>
-위에 for문에 var 변수 선언시 클로져 방식(즉시실행함수)으로 실행하지 않으면
for(var i=0 ; i<lis.length; i++){} 에서
함수 스코프를 갖는 var 변수 i 는 for문이 돌면서 값이 4로 지정됨.따라서 우리가 생각하기에 lis[0].onclick 를 하면 값이 0이 나올것이라 예상했지만 위와 같은 이유로 lis[0] , lis[1], lis[2], lis[3] 을 클릭하면 모두 값이 4로 나옴.따라서 이런 문제를 해결하기 위해서 클로져 방식으로 전역 변수의 범위를 갖는 i를 포문이 돌때마다 안에 즉시실행함수에 매개변수로 주어서지역변수로 만들어 주어야 우리가 원래 생각하던 거처럼lis[0] = 0lis[1] =1 lis[2] = 2 이렇게 값이 나옴.이런 경우와 대처법을 잘 기억해두도록 하자.
* const
const GENDER = "남자";
// var GENDER = "여자"; //에러
// GENDER = "여자"; //에러
const arr = ["홍길동", "이순신", "홍길자"];
// arr = ["김철수"]; //에러
arr[0] = "김철수"; //내부의 값 변경은 허용
arr.push("박영희"); //내부의 갑 변경 허용
//객체에서의 수정
const P1 = {"name" : "홍길동" };
// P1 = {"name" : "이순신"}; //P1을 전부 바꾸는 코드는 에러
P1.name = "이순신"; //내부의 값의 변경은 허용
P1.age = 20; //내부의 값의 추가도 허용
*확인
<body>
<script>
const gender = "남자";
// gender = "여자";
const arr = [1,2,3];
//arr = [1]; //배열을 통째로 변경 x
arr[0] = 10;
arr.push(4);
console.log(arr);
const obj = {name : "홍길동"};
// obj = {name: "이순신"}; //객체를 통째로 변경 x
obj["name"] = "이순신";
obj["age"] = 10;
obj["gender"] = "man of man";
console.log(obj);
</script>
</body>
2. spread operator (전개구문)
- 반복 가능한(iterable)에 적용할 수 있는 문법입니다.
- 배열이나 문자열 등을 아래처럼 풀어서 요소 하나 하나로 전개시킬 수 있습니다.
const arr = [1,2,3];
console.log(...arr); //num의 요소들을 추출
const str1 = 'hello';
const str2 = [...str1];
console.log(str2); // [ "h", "e", "l", "l", "o"]
//배열에서 전개구문
//배열의 추가
const num1 = [10, 20, 30, ...arr];
console.log(num1)
//배열의 중간추가
const num2 = [10, 20, ...arr, 30];
console.log(num2)
//배열의 복사
const num3 = [...arr]; //splice와 유사(복사)
console.log(num3)
//배열 연결
const num4 = [...arr, ...arr]
console.log(num4)
*확인
<body>
<script>
//전개구문 - 반복이 가능한 요소에서만 사용가능함
let arr = [1,2,3];
console.log(...arr); //전개구문
let str = "hello";
console.log(...str);
console.log([...str]);
//배열의 추가
let arr2 = [1,2,3, ...arr]; //123123
console.log(arr2);
//배열의 중간에 추가
let arr3 = [1,2,3, ...arr, 5]; //1231235
console.log(arr3);
//배열의 복사
let arr4 = [...arr];
console.log(arr4);
//배열의 연결
let arr5 = [...arr , ...arr2, ...arr3];
console.log(arr5);
</script>
</body>
<body>
<script>
function sum(x, y, z){
return x + y + z;
}
let arr = [1,2,3];
//sum(arr[0], arr[1], arr[2]);
console.log(sum(...arr)); //x, y, z
console.log(sum(10, ...arr)); //10, 1, 2, 3 -> 3은 나가리. 함수의 매개변수는 x, y, z로 3개이기때문
//함수를 선언시 - 가변적매개변수(반드시 맨 마지막에 선언)
function sum2(x, ...y){
return [x, ...y];
}
console.log(sum2(1));
console.log(sum2(1,2));
console.log(sum2(1,2,3));
console.log(sum2(1,2,3,4));
//함수의 default매개변수
function sum3(x, y = 10, z = 100){
return x + y + z;
}
console.log(sum3(1)); //111
console.log(sum3(1,2)); //103 , x = 1 , y = 2
console.log(sum3(1,2,3)); //6
console.log(sum3(...arr)); //6
</script>
</body>
- 매개변수 자리에 ...a 이렇게 가변적 매개변수를 줄수 있는데 이 가변적매개변수는 반드시 맨 마지막에 선언되야 한다. - 함수의 매개변수에 default 값을 줄 수 있다.
- 전개구문은 반복이 가능한 요소에서만 사용가능하다는 점 잘 기억해두자.
3. 함수에서 spread operator
const num = [1,2,3];
//함수의 전달
function sum(x, y, z) {
return x + y + z;
}
console.log( sum(...num) ); //num의 요소를 x,y,z로 전달
console.log( sum(10, ...num) ); //10, 1, 2, 3을 전달
//함수의 매개변수의 사용(가변적 매개변수) - 단 마지막에 작성해야 합니다.
function sum2(x, ...arr) {
return [x, ...arr]; //리스트 반환
}
console.log( sum2("홍길동", 1) )
console.log( sum2("홍길동", 1,2) )
console.log( sum2("홍길동", 1,2,3) )
//함수의 default매개값
function sum3(x, y = 10, z = 100) {
return x + y + z;
}
console.log( sum3(1) ) //111
console.log( sum3(1, 2) ) //103
console.log( sum3(1, 2, 3) ) //6
console.log( sum3(...[1,2] )) //1,2를 추출해서 전달 //103
3. Destructuring assignment (구조 분해 할당)
1. 배열에서 destructuring
-배열에서 의 값을 가져와서 담을 때는
let [] 이렇게 let 옆에 대괄호를 쓰고 그 안에 변수 설정을 해준다.
let arr = ["홍길동", "이순신", "홍길자", "김철수"];
/* 기존의 방법
let n1 = arr[0];
let n2 = arr[1];
let n3 = arr[2];
let n4 = arr[3];
*/
//위치요소를 반환받아서 한번에 사용한다.
let [a,b,c,d] = arr;
console.log(a,b,c,d)
let [n1, , ,n2] = arr;
console.log(n1, n2)
//전부다 반환한다.
let [...x] = arr;
console.log(x);
//남아있는 모든 요소를 반환한다.
let [k1, k2, ...all] = arr;
console.log(k1, k2, all)
*확인
<body>
<script>
let arr = [1,2,3,4];
// let a1 = arr[0];
// let a2 = arr[1];
let [a, b, c, d] = arr;
console.log(a);
console.log(b);
console.log(c);
console.log(d);
let [a1, a2] = arr;
console.log(a1, a2); //1, 2
let[k1, , , k4] = arr;
console.log(k1, k4); //1, 4
let [y1, ...y2] = arr;
console.log(y1, y2); //1, [2,3,4]
let[...ar] = arr;
console.log(ar); //[1,2,3,4]
function useState(){
return [1, function(){}];
}
let [n1, n2] = useState();
console.log(n1, n2); //1, function
</script>
</body>
2. 객체에서 destructuring
-객체에서 값을 가져와 담을때는
let {} 이렇게 중괄호 안에 변수를 넣어 준다.
let person = {
"name": "김철수",
"age" : 30,
"job" : ["programmer", "designer"]
}
//name키 값을 가져온다.
let {name} = person;
console.log(name);
let {name, age, job} = person;
console.log(name, age, job);
//다른 이름으로 가져오기
let {name: aaa, age:bbb} = person; //name을 aaa이름으로 가져온다
console.log(aaa, bbb)
*확인
<body>
<script>
let obj = { name: "홍길동", age: 20 };
// console.log(obj.name); 기본
// console.log(obj["name"]);
// let {name} = obj;
// console.log(name);
// let { name, age } = obj;
// console.log(name, age);
//여기 헷갈렸음 종종 봐주기
let{...arr} = obj;
console.log(arr); //객체
let person = {
name : "홍길동",
age : 30,
job : ["js", "css"],
info : {id: "aaa123"}
};
// let{name, job} = person;
// console.log(name, job);
// let{name, job, info} = person;
// console.log(name, job, info)
//객체의 값을 다른 이름으로 가지고 나오기
let{name: aaa} = person; //name을 aaa이름으로 가지고나오기
console.log(aaa);
let{name: bbb, job: jjj} = person;
console.log(bbb, jjj);
</script>
</body>
* 헷갈렸던 부분
객체의 키 값을 불러오는 방법 중 하나는
-객체이름["키"] 이렇게 갖고오는것. 또 다른 방법은
-객체.키
let{...arr} 의 의미는 obj에 있는 모든 값을 담는다는 의미라고 볼 수 있다.
따라서
let{...arr}은 obj 객체를 담는것과 마찬가지 그래서 arr을 출력하면
{ name: "홍길동", age: 20 }; 이 나옴.
*JSON 형식에서 디스트럭쳐링
-많이 헷갈렸던부분 주의해서 봐두자.
- 기억할 포인트
1. 객체의 값을 가져오거나 담을 때는 {} 로
2. 배열의 값을 가져오거나 담을 때는 [] 로
감싸준다는것을 포인트로 봐두자.
4. for of문
1. 반복 가능한 객체(iterable)를 for문 안에서 반복시켜 연속된 결과값을 얻습니다.
2. forEach문에서 지원하지 않는 break, continue, return의 사용가능
* for in 구문
for(let i in arr){}; 은
i 변수에 배열의 인덱스 값을 담아주는 것.* for of문for(let i of arr){}; 은i 변수에 배열의 값을 담아준다것.
위 두 구문의 차이점을 잘 기억해두자. *객체를 반복할 수는 없습니다.
<body>
<script>
let arr = ["a", "b", "c"];
// for(let i in arr){
// console.log(i); //index
// }
for(let i of arr){
console.log(i); //value
}
for(let i of "hello world"){
console.log(i);
}
let person = [
{id: "aaa", age : 10},
{id: "bbb", age : 20}
];
//구조분해할당
for(let {id, age} of person ){
console.log(id);
console.log(age);
}
//객체를 반복할순 없음
let obj = {a : 1, b: 2};
for(let i of obj){
console.log(i);
}
</script>
</body>
5. Backtick
1. 백틱 `을 용해서 문자열을 표현하고, 템플릿 리터럴 ${}를 이용해서 필요값을 처리
* 백틱` 으로 감싸준 문자열 구문 안에서 변수를 참고하고싶으면 ${변수명} 이렇게사용하면 됨.
<body>
<script>
let name = "이순신";
let age = 20;
console.log("이름은:" + name + "이고, 나이는:" + age + "입니다");
console.log(`이름은:${name} 이고, 나이는:${age}입니다`); //`은 tab위에 키
</script>
</body>
6. Arrow Function (화살표함수 👍) ★★★
1. 화살표 함수는 기본적으로 익명함수를 대체합니다.
(호이스팅 불가 - 아래 선언해놓은 함수를 위에서 호출해서 사용하는것이 안됩니다.)
*되돌아보기
-주의! 인터프리터 언어의 특성상 함수를 위쪽에 선언했느냐 아래 쪽에 선언했느냐가 중요하다.
(선언적 함수 이외에는 위에서 함수를 선언해놔야 아래에서 호출해서 사용가능)
- 익명함수는 선언적함수처럼 호이스팅(아래쪽에 선언된 함수를 위에서 호출해서 사용)이 안됨.
그러니 꼭 위쪽에 함수를 선언하고 아래쪽에서 사용해주도록 하자.
2. 가독성이 향상됩니다.
문법1
코드가 한개줄이면 {} 생략이 가능하다
{}를 쓰지 않으면 기본값으로 undefined를 반환합니다.
{}를 쓰지 않고 구문을 작성하면 리턴문이 됩니다.
let b1 = (a) => console.log(a); //출력
console.log( b1(1) ); //undefined
let b3 = (a, b) => a + b; //리턴문
console.log( b3(1, 2) ); //3
문법2
매개변수가 1개라면, 매개변수 자리의 ()의 생략이 가능합니다.
let func = a => a + 10;
console.log ( func(10) ); //20
문법3
객체를 반환 할때는 ()를 묶어 줍니다.
//1st
let c = () => {
return {key: '홍길동'};
}
//2nd
let d = () => ({key: '이순신'});
*확인
<body>
<script>
//기본적으로 익명함수를 대체합니다.
// var a = function(){
// console.log("a실행");
// }
// a(); 호이스팅이 안되기 떄문에 에러 발생
let a = () => {
console.log("a실행");
}
a();
/*
문법1 -
코드가 한줄이면 {} 생략이 됩니다.
{}를 생략하면 자동으로 return이 붙습니다.
*/
let b1 = () => console.log("b1실행");
b1();
let b2 = (a,b,c) => a + b + c ;
console.log(b2(1,2,3));
let b3 = (a=10) => a + 100; //a 의 매개변수에 10을 디폴트 값으로 줬음.
console.log(b3()); //110
console.log(b3(20));//120
/*
문법2 - 매개변수가 1개라면 () 생략이 됩니다.
*/
let c1 = a => a + 10;
console.log(c1(10));
/*
문법3 - 객체를 반환할 때는 ()로 묶어줍니다.
*/
let c2 = () => {
return {key: 1, age: 20};
};
let c3 = () => ({key: 1, age: 20})
console.log(c3());
//
// setInterval(function(){
// console.log(1);
// },1000)
setInterval(() => console.log(1), 1000);
</script>
</body>
화살표 함수의 응용 forEach, filter, map
1. forEach - 반복문
*단순한 순회의 용도
* forEach 구문은 반복을 돌면서
forEach 구문안의 콜백함수의 매개변수 값에있는 값, 인덱스, 현재배열 의 값을 출력해줍니다.
array.forEach(callbackFunction(currenValue, index, array), thisArg)
- currenValue: 현재값
- index: 현재인덱스
- array: 현재배열,
- thisArg: callbackFunction 내에서 this로 사용될 값
//1st
list.forEach( function(x, y, z) {
console.log(x, y, z);
});
//2nd
list.forEach( (x,y,z) => console.log(x,y,z) )
2. filter - 요소개수만큼 반복하며 boolean을 이용한 새로운 list를 만듬 ★★★
*콜백 함수 리턴에 true 인 값들로만 담아서 새로운 배열로 만들어 다시 리턴해줌.
*필터함수 안에 콜백함수의 구현부분에 조건을 달아주면
조건의 값에 해당하는 값들로 구성된 배열을 만들어 반환해줍니다.
array.filter(callbackFunction(currenValue, index, array), thisArg)
var result = list.filter( function(x, y, z) {
return x % 2 == 0; //요소가 true인결과를 반환(요소들의 짝수만 반환)
});
console.log(`result: ${result}`); //2, 4, 6, 8, 10
//2nd
var result = list.filter( (x, y, z) => x % 2 == 0);
3. map - 실행한 결과를 가지고 새로운 배열을 만들 때 사용
* 위에말처럼 함수 구현부에 실행한 결과 값들로 구성된 배열을 만들어서 리턴해줍니다.
array.map(callbackFunction(currenValue, index, array), thisArg)
//1st
var result2 = list.map( function(x, y, z) {
return x * x; //처리한 연산결과를 반환
});
console.log(`result2: ${result2}`); //1, 4, 9, 16 ... 100
//2nd
var result2 = list.map( x => x * x );
*확인
<body>
<script>
//forEach(콜백함수, thisArg:옵션) thisArg:옵션은 사용안함, 옵션이기도 하고 신경안써도 됨.
//forEach(function(현재값, 인덱스, 현재배열){}, thisArg)
let arr = ["a", "b", "c", "d"];
// arr.forEach(function(value, index, arr){
// console.log("값:" + value + ", 인덱스:" + index + ", 현재배열:" + arr);
// })
// arr.forEach(function(value){
// console.log(value);
// })
// arr.forEach((value, index, arr) => {
// console.log(`값 ${value}, 인덱스 ${index}, 현재배열 ${arr}`)
// });
// arr.forEach(value => console.log(value));
//필터함수
//filter(콜백(값, 인덱스, 현재배열), thisArg)
let arr2 = [1,2,3,4,4,5,6,7,8,9,10];
// let result = arr2.filter(function(a, b, c){
// // console.log(a, b, c);
// // return a >= 5;
// return a % 2 == 0;
// });
// console.log(result);
// let result = arr2.filter( a => a%2 == 0);
// console.log(result);
//배열요소중에 o가 들어간 문자열만 필터링
// let arr3 = ["melon", "apple", "orange", "grape", "mango"];
// let result = arr3.filter((a) => a.includes("o")); //방법1
// let result2 = arr3.filter((a) => a.indexOf("o") != -1); //방법2
// console.log(result);
// console.log(result2);
//map함수 - 실행한 결과를 가지고 새로운 배열을 만들 때 사용
//map(콜백(현재값, 인덱스, 현재배열), thisArg)
let arr4 = [1,3,5,7,9];
// let result = arr4.map(function(a,b,c){
// return a + 1 ;
// })
// console.log(result);
// let result = arr4.map( a => a + 1);
// console.log(result);
//실습
let arr3 = ["melon", "apple", "orange", "grape", "mango"];
let result = arr3.filter( a => a.includes("o")).map( (a,b) => `o가 들어간 과일중 ${a}은 ${b+1}번째 입니다` );
console.log(result);
</script>
</body>
7. class
일반HTML에서는 굳이 class를 사용하진 않습니다. ★
React의 class컴포넌트를 사용한다면 알아두세요.
1. 클래스의 멤버변수를 선언할 때는 키워드를 사용하지 않습니다. (구형브라우저에서는 지원불가 할 수 있음)
ex) let name = "홍길동"; 이렇게 name 앞에 let 을 붙여주면 문법적 오류가 발생합니다.
*생성자
-자바스크립트의 생성자는 1개입니다. (생성자 중복불가)
-생성자에 매개변수를 추가하고 따로 기본생성자를 만들지 않더라도
기본 생성자 호출이 허용 됩니다.
-멤버변수는 선언하지 않더라도 this.변수명을 지칭하면 자동 생성됩니다.
<body>
<script>
class Person{
//멤버변수
//변수 선언시 앞에 let을 붙이면 문법적 오류가 발생
name = "홍길동";
age = 20;
state = {a : 1};
//생성자는 JS에서 반드시 1개입니다
//JS는 this키워드를 지칭하면 멤버변수가 됩니다
constructor(addr){
this.addr = addr; //선언한적이 없지만 this.변수명 을 통해서 자동으로 addr이 멤버변수가 됨.
}
//함수
func = () => {
console.log("func실행");
}
}
//객체로 생성 - 기본 생성자가 없더라도 허용됩니다.
let p = new Person();
console.log(p.name); //멤버변수 접근
console.log(p.age); //멤버변수 접근
console.log(p.state.a); //멤버변수 접근
p.func();
//객체생성
let p2 = new Person("서울");
console.log(p2.addr);
</script>
</body>
#클래스 상속
*자식클래스의 생성자 안에 super(); 로 반드시 부모와 연결 시켜줘야함.
(자바처럼 자동으로 생성되지 않기때문)
*get, set, static 예약어로 메서드를 설정할 수 있는데 .
이부분은 잘 안씀.
<body>
<script>
class Shape {
constructor(){
}
func = () => {
console.log("func호출");
}
}
class Rect extends Shape {
//프로그래머가 생성자를 직접만들게 되면 super()를 통해 연결해야 합니다.
constructor(w, h){
super(); //부모의 생성자 연결
this.w = w; //멤버변수에 w 저장
this.h = h;
}
//set
setW = (w) => {
this.w = w;
}
//get
getW = () => {
return this.w;
}
//set, get, static 같은 키워드들로 함수를 설정 할 수 있습니다.
}
//객체생성
let rect = new Rect();
rect.func(); //물려받음
//객체생성2
let rect2 = new Rect(10, 20);
console.log(rect2.w);
console.log(rect2.h);
rect2.setW(30);
console.log(rect2.getW());
</script>
</body>
8. module import export
* 모듈 임포트
- 모듈은 JS ES6문법에서 미리 작성해 놓은 스크립트 파일이며, 모듈 안에는 변수, 함수, 클래스 등이 정의되어 있습니다.
- ES6부터는 주요기능들을 모듈로 구성하여 사용이 가능합니다.
- 모듈을 내보내는 방법은 named export방식과 default export방식 2개가 있습니다.
- 여러 값을 내보낼 때 named export방식
- 단일 값을 내보낼 때 default export방식
* 여러 값을 내보낼 때 named export방식
script01.js
//내보내기 1
export const name = '홍길동';
export const age = 20;
export const getInfo = () => {
console.log('이름:', name, '나이:', age);
}
//내보내기2
let sum = 0;
let add = (x) => {
sum += x;
console.log(sum);
}
export {sum, add}; //선언해논 변수를 export{} 로 내보내기
★ './script01.js' 에서처럼./ 써주면 상대경로로 참조한다는 것.
script01.html
- HTML5파일에서 예외적으로 module을 사용할려면 type="module" 문을 반드시 작성합니다.
* import 방법1 destructuring 방식
* import방식2 Alias 방식에서
- as test 라는 의미는 from js 파일에서 가져온 모든것을 test 라는 이름으로 참조해서 쓴다는 의미.
위 두가지방식이 일반적입니다.
<script type="module">
//HTML5표준에서 예외적으로 module을 사용할려면 type="module" 문을 반드시 작성합니다.
//import방법1 (Destructuring방식)
import {name, age, getInfo} from './script01.js';
console.log(name);
console.log(age);
getInfo();
//import방법2 (Alias방식)
import * as test from './script01.js';
console.log(test.name);
console.log(test.age);
test.getInfo();
console.log(test.sum);
test.add(10);
//import방법3 (이름바꿔 가져오기);
import {name as n, age as a, getInfo as get} from './script01.js';
console.log(n);
console.log(a);
get();
</script>
*단일 값을 내보낼 때 default export방식
하나의 모듈에서 하나의 객체를 이름으로 내보낼 때 단일 객체 내보내기 export default문을 사용합니다.
Class나 함수를 내보낼떄는 세미콜론을 붙이지 않도록 권유됩니다.
index02.js
*default 가 붙으면 하나만 내보낼수 있다는 점 기억해두기.
class Person{
constructor(name, age){
this.name = name; //멤버변수
this.age = age;
}
getInfo = () => {
return `이름${this.name}, 나이${this.age}`;
}
}
//default구문은 반드시 1개여야 합니다.
export default Person;
index02.html
<body>
<script type="module">
import Person from './index02.js';
const p = new Person('hong', 20);
console.log(p.getInfo());
</script>
</body>