본문 바로가기

블록체인_9기/💛 JAVASCRIPT

18강(과제X)_230327_Javascript(구조 분해 할당, 스프레드 연산자, swiper)

728x90

 

 

 

 


구조 분해 할당

기존의 ES5 문법에서 배열의 값을 호출하여 변수에 담거나 사용할 때에는 해당 방법으로 하나씩 인덱스를 사용해서 값을 하나씩 전달하였다.

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

one = arr[1];  
two = arr[3];

console.log(one,two);
//결과: 2 4

그러나 ES6가 도입되면서 구조분해 할당이 들어섰고 변수를 선언하고 배열의 값을 구조분해 할당을 하여 순서대로 배열의 값을 할당할 수 있게 되었다.

let arr2 = [1,2,3];
let [one1,two1,three1] = arr2;

console.log(one1,two1,three1);
//결과: 1 2 3

따라서 구조 분해 할당은 객체나 배열을 변수로 분해 할 수 있게 해주는 특별한 문법이라고 할 수 있다.

'분해(destructuring)'는 '파괴(destructive)'를 의미하지 않는다.

구조 분해 할당은 어떤 것을 복사한 이후에 변수로 분해해 준다는 의미로 붙여졌다. 구조 분해 할당 과정에서 분해 대상은 수정 또는 파괴되지 않는다. 기존 인덱스를 이용하여 값을 전달하는 방법과의 차이점은 코드의 양이 줄어든다는 점이다.

//구조 분해 할당 사용 시 코드
let [firstName, surname] = arr;

//인덱스를 이용하여 값 대입 시 코드
let firstName = arr[0];
let surname = arr[1];

 

쉼표( , )를 사용하여 요소 무시하기

쉼표( , )를 사용하면 필요하지 않은 배열의 요소를 버릴 수 있다.

// 두 번째 요소는 필요하지 않음
let [firstName, , title] = ["Julius", "Caesar", "Consul", "of the Roman Republic"];

alert( title ); // Consul
//4번째 요소는 할당할 변수가 없기 때문에 생략되었다.

 

할당되는 배열의 요소가 없으면 'undefined'

let [c,d] = [1];
console.log(c,d);
//결과: 1 undefined

 

변수와 객체에 디폴트 값도 추가할 수 있다.

//변수에 디폴트 값 추가
let [a,b,c=1] = [1,2];
console.log(a,b,c);
//결과: 1 2 1


//객체의 디폴트 값 추가
let name4 = {firstName = "lee2", lastName} = {lastName: "kim"};
console.log(firstName, lastName);
//결과: lee2 kim

 

문자의 길이를 구할 수도 있다.

//문자열을 담은 변수에서
let str = "afdsaf";
//str.length : 문자열의 길이를 구하는 방법이었다.

//구조분해할당으로 변수에 할당
let {length} = str;

console.log(length);
//결과: 6

 

객체안에 필요한 값만 호출해서 사용할 수 있다.

let list = [{id : 1, content : "sdfsdg", isActive: true},
            {id : 2, content : "sdfsdg", isActive: true},
            {id : 3, content : "sdfsdg", isActive: true},
            {id : 4, content : "sdfsdg", isActive: true}];

//id값만 뽑아오자
list.forEach(function(i){
    let {id} = i;
    console.log(id);
})
/*결과: 
1
2
3
4
*/
//list객체에서 id 키값만 구조분해 할당 해줄 수 있다.

 

 

let user = {
    name : "lee",
    address : {
        city: "seoul"
    }
}
//구조분해 할당으로 city값을 할당해보자
let {address:{city}} = user;
console.log(city);
//결과: seoul

 

 


스프레드 연산자

  • 본래의 객체를 변경하지 않고 새로운 객체로 만들어준다.
  • 객체의 경우에는 주소를 참조하는 래퍼런스 타입이기 때문에 같은 키의 값이 바뀌게 되지만, 스프레드 연산자는 새로운 객체를 만드므로 원본을 변경하지 않는다.
  • 사용 예시로는, 데이터베이스에서 값을 가져와서 검색기능을 만든다고 가정하면 모든 리스트를 가지고 있는 배열은 유지하되 검색기능으로 걸래낸 배열만을 사용하고 싶을 때 등으로 사용할 수 있다.
let temp1 = [1,2,3];
let temp2 = [4,5,6,7];

let temp3 = [...temp1,...temp2];
console.log(temp3);
//결과: [1, 2, 3, 4, 5, 7]
//스프레드 연산자는 값만 참조한다.

let obj = {
    a:1,
    b:2
}
let obj2 = {
    a:2,
    b:3,
    c:1
}
let obj4 = {
    a:3,
    b:4,
    c:4
}

//키가 동일할 경우 마지막 값으로 할당된다.
let obj3 = {...obj,...obj2,...obj4};
console.log(obj3);
//결과: [a: 3,b: 4,c: 4]
let obj = {name : 'jiwon', content : "내용"};
let obj2 = obj;

//객체는 주소를 참조하는 래퍼런스 타입이기 때문에 같은 키의 값이 바뀌게 된다.
obj2.name = "kim"

console.log(obj);
//결과: {name: 'kim', content: '내용'}
console.log(obj2);
//결과: {name: 'kim', content: '내용'}
console.log(obj == obj2);   //주소 참조까지 같다 true

// ... : 스프레드 연산자 구문
let obj3 = {...obj};
//값을 복사해서 새로운 객체를 만들어 준 것
obj3.name = "kim2"
console.log(obj3);
//결과: {name: 'kim2', content: '내용'}
console.log(obj == obj3);   //값만 복사해서 원본을 유지하고 새로운 객체를 만드므로 false

 

 

👩‍🏫구조분해 할당 예시_ 객체를 배열로 만들어서 키값을 기준으로 변수처럼 사용

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <div>
        <ul class="list">

        </ul>
    </div>
</body>
<script>
    //객체를 배열로 담아놓고
    let list = [{id : 1, content : "list01", name : "lee1"},
                {id : 2, content : "list02", name : "lee2"},
                {id : 3, content : "list03", name : "lee3"},
                {id : 4, content : "list04", name : "lee4"},
                {id : 5, content : "list05", name : "lee5"}];
    //배열의 갯수만큼 forEach 반복문
    list.forEach(function(i){
        //li tag 생성
        let _li = document.createElement("li");
        //span tag 생성
        let _span1 = document.createElement("span")
        let _span2 = document.createElement("span")
        let _span3 = document.createElement("span")
        //배열의 순서대로 객체를 구조분해 할당으로
        //키값 기준 id, content, name
        //선언된 id, content, name을 변수처럼 사용
        //객체의 키 값이 동일해야 한다.
        let {id, content, name} = i;
        _span1.innerHTML = "번호 : " + id;
        _span2.innerHTML = "내용 : " + content;
        _span3.innerHTML = "작성자 : " + name;
        _li.append(_span1,_span2,_span3);
        //document.querySelector(".list") 선택자로 선택된 태그 반환
        //반환값에 .작성해서 바로 메소드 호출
        document.querySelector(".list").append(_li);

    })

</script>
</html>

 

👩‍🏫구조분해 할당 예시_ lotto

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .lotto-box,
        .lotto-box2{
            display: flex;
            flex-wrap: wrap;
        }
        .lotto-box div,
        .lotto-box2 div{
            border: 8px solid;
            width: 30px;
            height: 30px;
            display: flex;
            justify-content: center;
            align-items: center;
            border-radius: 50%;
        }
    </style>
</head>
<body>
    <div>Lotto</div>
    <h1>로또 박스</h1>
    <div class="lotto-box">
    </div>
    <div class="lotto-box2">
    </div>
    <button class="lotto-btn">로또 추첨</button>
</body>
<script>
    let lottoBtn = document.querySelector(".lotto-btn");
    let lottoNum = [];
    let lottoReslut = [];
    function init(){
        //1~45까지
        for (let i = 1; i <= 45; i++) {
            lottoNum.push(i);
            //div태그 하나 만들고
            let _div = document.createElement('div');
            //클래스 이름 숫자로 넣고
            _div.className = "item" +i;
            //만든 div태그의 내용 숫자 추가
            _div.innerHTML = i;
            //만들어진 div태그 lotto-box클래스를 가진 태그의 내용으로 추가
            document.querySelector(".lotto-box").append(_div);
        }
    }
    init();
    //lottoBtn tag를 클릭하면
    lottoBtn.addEventListener("click",function(){
        //클릭하면 구문실행
        //6개 뽑아야하고 중복 안되게
        //lottoReslut배열의 길이가 6보다 작으면 계속 반복한다.
        while(lottoReslut.length < 6){

            //1~45랜덤 값 구하고
            let num = parseInt(Math.floor(Math.random() * 45) + 1);
            //배열안에 값이 없으면 -1
            if(lottoReslut.indexOf(num) === -1){
                
                //중복이 되지 않는 값이니까 배열에 추가
                lottoReslut.push(num);
                //배열에는 값을 추가했고 html에 띄워놓은 구슬들을 옮겨준다.
                let lottoItem = document.querySelector(".item"+num);
                
                //ex) item1, item24
                document.querySelector(".lotto-box2").append(lottoItem);  
            }
            //구조분해 할당 배열은 순서대로 
            //변수의 명이 어떻든 상관없이 순서대로 할당 받는다.
            let [text1, text2, text3, text4, text5, text6] = lottoReslut;
            console.log(text1, text2, text3, text4, text5, text6, "당첨번호");
        }
    })
</script>
</html>
Document
Lotto

로또 박스

 

 


swiper

  • 만들어져 있는 것을 가져다가 사용할 수도 있다.
 

Swiper Demos

Swiper is the most modern free mobile touch slider with hardware accelerated transitions and amazing native behavior.

swiperjs.com

  • 외부 swiper 사용 시
    • 외부 css, js 등이 있으므로 인터넷이 끊기면 정상적으로 작동되지 않을 수 있다.
      • (해당 부분의 min파일을 복사하여 파일로 저장시켜 주면 실행이 가능하다.)
    • swiper 제작자가 사용 규격을 맞추어 놓은 것으로 클래스 등을 동일하게 사용하도록 주의하여야 한다.
    • swiper 생성자에 매개변수로 태그의 선택자를 전달하면 된다.
      • 생성자의 두 번째 매개변수에는 속성 값을 넣어줄 수 있다.
...

<body>
<!--생성자로 속성값을 전달받는 mySwiper 클래스-->
  <div class="swiper mySwiper">
    <div class="swiper-wrapper">

      <div class="swiper-slide">Slide 1</div>
      <div class="swiper-slide">Slide 2</div>
      <div class="swiper-slide">Slide 3</div>
      <div class="swiper-slide">Slide 4</div>
      <div class="swiper-slide">Slide 5</div>
      <div class="swiper-slide">Slide 6</div>
      <div class="swiper-slide">Slide 7</div>
      <div class="swiper-slide">Slide 8</div>
      <div class="swiper-slide">Slide 9</div>
    </div>
  </div>
  
  <script>
    var swiper = new Swiper(".mySwiper", {
        loop:true,
        slidesPerView: 2,   //한 화면에 보일 슬라이드 개수
        spaceBetween: 30}); //슬라이드 사이의 여백
  </script>
</body>

 

👩‍🏫스와이프 예시&실습_드래그, 버튼 클릭 시 작동하는 스와이프 만들기

실습내용

  • 민감도 수치
    • x좌표의 차이 값이 50이상일 경우 동작 (50 / -50)
  • 루프속성
    • 마지막 루프를 이동했을 때 자연스럽게 첫 루프가 나오도록 무한루프 제작
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
//클릭의 시작 위치를 가지고 있고
//끝나면 끝난 좌표와 비교해서
//오른쪽으로 스와이프 된 건지 왼쪽으로 스와이프 된 건지부터
//확인을 하고 인덱스를 기준으로 움직임을 제어해보자

//마우스 클릭의 시작지점 X좌표
let _start;
//진행중인 인덱스
let _index = 1;

let _swiper = document.querySelector('.swiper');        //스와이퍼의 전체영역
let _swiperContent = document.querySelector('.swiper-content')      //스와이퍼 이미지 영역
let {length} = document.querySelectorAll('.swiper-item');       //각 스와이퍼
let _prev = document.querySelector('.prev');        //이전 버튼
let _next = document.querySelector('.next');        //다음 버튼

console.log(length);
//getComputedStyle 적용된 스타일의 값을 가져올 수 있다.
//적용된 스카일을 가져올 태그를 매개변수로 전달
let _swiperWidth = parseInt(getComputedStyle(_swiper).width);   //스와이퍼의 가로사이즈. parseInt로 500px -> 500으로 변경
console.log(_swiperWidth)

_swiper.addEventListener("mousedown", function(e){      //스와이퍼 영역에서 드래그로 스와이퍼 이동하기 위한 이벤트 함수
    console.log("클릭시작");        //스와이퍼 영역에서 클릭 시작 시 동작
    //클릭했을 때 X좌표가 필요
    console.log(e);         //클릭 시, 클릭한 곳의 좌표에 대한 정보를 알려준다.
    //클릭한 x의 좌표
    //e.clientX;
    _start = e.clientX;     //_start는 클릭 시 x좌표 값이다.
    console.log(_start);
})

_swiper.addEventListener('mouseup',function(e){     //스와이퍼 영역에서 드래그로 스와이퍼 이동하기 위한 이벤트 함수. 클릭후 마우스를 뗐을 경우 발생
    if(_start - e.clientX > 50){        //클릭 시 x좌표가 뗐을 때의 좌표보다 값이 50이상 컸을 경우
        console.log("끝 좌표가 더 작아");
        if(_index < (length - 1) ){     //인덱스가 배열의 길이 -1보다 작을 경우
            _index++;       //인덱스의 값은 1씩 증가한다. 따라서 오른쪽으로 넘어가는 슬라이드가 진행된다.
            swiperMove();   //스와이퍼 영역에서 노출될 스와이퍼를 결정하기 위해서 실행되는 함수.
            _swiperContent.style.transition = '1s';     //setTimeout 동작에서 transition 의 값을 안주면 다른 모션까지 안들어가서 다시 1s 부여
            if(_index == 5){        //스와이프가 노출하고자하는 영역(_index1,2,3,4)을 지나가게 되면
                setTimeout(() => {                 //시간차로 동작을 하게된다.
                    _swiperContent.style.transition = '0s';     //슬라이드 시 무빙을 없애고
                    _index = 1;     //인덱스 값을 가장 처음으로 노출하고자 하는 값인 1로 이동
                    _swiperContent.style.left = -500 + "px";    //슬라이드 노출영역을 인덱스 1의 위치인 x좌표 값으로 지정
                }, 1000);       //1초 안에 setTimeout이 동작한다.
            }
        }
        console.log(_start - e.clientX);
    }
    else if(_start - e.clientX < -50){      //클릭 시 x좌표가 뗐을 때의 좌표보다 값이 -50이상 작았을 경우
        console.log("끝 좌표가 더 커");
        if(_index > 0){     //인덱스가 0보다 클 경우
            _index--;       //인덱스의 값은 1씩 감소한다. 따라서 왼쪽으로 넘어가는 슬라이드가 진행된다.
            swiperMove();   //스와이퍼 영역에서 노출될 스와이퍼를 결정하기 위해서 실행되는 함수.
            _swiperContent.style.transition = '1s';     //setTimeout 동작에서 transition 의 값을 안주면 다른 모션까지 안들어가서 다시 1s 부여
            if(_index == 0){    //인덱스의 값이 0일 경우
                setTimeout(() => {                //시간 차로 동작을 진행하게 된다.
                    _swiperContent.style.transition = '0s';     //슬라이드 시 무빙을 없애고
                    _index = length-2;       //인덱스 값을 가장 마지막으로 노출하고자 하는 값인 (length-2 -> length -1은 노출을 희망하지 않으므로)로 이동
                    _swiperContent.style.left = -2000 + "px";   //슬라이드 노출영역을 인덱스 4의 위치인 x좌표 값으로 지정
                }, 1000);       //1초 안에 setTimeout이 동작한다.
    
            }
        }
        console.log(_start - e.clientX);
    }
})

//인덱스를 기준으로 움직임

function swiperMove(){      //노출될 영역에 어떤 스와이프 값을 넣을 지 결정하는 함수
    _swiperContent.style.left = -(_index * _swiperWidth) + "px";    //인덱스번호 * 스와이프 가로영역
}
swiperMove();

_prev.addEventListener('click',function(){      //'이전'버튼 클릭시 이전 인덱스를 보여줄 것을 동작할 이벤트 함수
    
    if(_index > 0){     //인덱스 값이 0보다 크다면
        _index--;       //인덱스가 1씩 감소한다.
        swiperMove();       // 감소한 인덱스 값으로 스와이프 영역에 노출될 스와이프를 결정한다.
        _swiperContent.style.transition = '1s';     //setTimeout 동작에서 transition 의 값을 안주면 다른 모션까지 안들어가서 다시 1s 부여
        if(_index == 0){        //인덱스 값이 0이라면
            setTimeout(() => {                
                _swiperContent.style.transition = '0s';
                _index = length-2;
                _swiperContent.style.left = -2000 + "px";
            }, 1000);

        }
    }

})

_next.addEventListener('click',function(){      //'다음'버튼 클릭스 다음 인덱스를 보여줄 것을 실행할 함수
    if(_index < (length - 1)){      //인덱스가 인덱스길이-1보다 작다면
        _swiperContent.style.transition = '1s';     //setTimeout 동작에서 transition 의 값을 안주면 다른 모션까지 안들어가서 다시 1s 부여
        _index++;       //인덱스가 1씩 증가한다.
        swiperMove();       //증가된 인덱스 값으로 노출영역에 노출될 스와이프의 값을 정한다.
        if(_index == 5){        //인덱스 값이 5라면
            setTimeout(() => {                
                _swiperContent.style.transition = '0s';
                _index = 1;
                _swiperContent.style.left = -500 + "px";
            }, 1000);
        }
    }
})
</script>
</html>
Document
728x90