function getToday() {
    var date = new Date();
    var year = date.getFullYear();
    var month = ("0" + (1 + date.getMonth())).slice(-2);
    var day = ("0" + date.getDate()).slice(-2);
    return year + month + day;
}

20221207

 

function formatDate(start, end, index) {
    if (index == 1) {
        return getToday().slice(start, end) + '년 '
    }
    if (index == 2) {
        return getToday().slice(start, end) + '월 '
    }
    if (index == 3) {
        return getToday().slice(start, end) + '일'
    }
}

2022년12월07일

Window 객체

자바스크립트의

최상위 객체,

전역 객체,

모든 객체가 소속된 객체

이다. (가장 큰형님) 자바로 치면 Object 쯤 되는 객체 되시겠다.

우리가 곧 공부 할 내용인

DOM , BOM , JavaScript(CORE) 도 모두 window 를 형님으로 모시고 있다.

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

‘객제지향모델’ 로써 구조화된 문서를 표현하는 형식이다.

(완전 내 마이웨이 대로 설명하면, 디자인 패턴 같은 하나의 형식 이라는 이야기 같다.)

텍스트 파일로 이루어진 웹 문서를 브라우저에 렌더링 하려면 웹 문서를 브라우저가 이해할 수 있는 구조로 메모리에 올려야 한다.

여기서 브라우저가 웹 문서를 쉽게 이해할 수 있도록 구성된 형태를 DOM 이라고 하는 것이다.

모든 요소들 과의 관계를 부자 관계로 표현할 수 있는 트리 구조이다.

주로 만나게되는 노드 4가지

문서 노드(Document Node)

트리의 최상위에 존재하며 각각의 하위 요소들(Element, Attributes, Text)에 접근하려면 이 노드를 거쳐야한다. 예시(document.getElement ~

요소 노드(Element Node)

쉽게 말하자면 태그 이름이다. <div> 의 요소는 div 이고, <img>의 요소는 img …

(심화)  아직은 이해가 안되지만 일단 적어둠

JS DOM 에서 Node 는 node의 constructor 이고, HTMLElement는 element의 constructor이다.

paragraph는 node이자 동시에 element이다.

어트리뷰트 노드 (속성 노드, Attribute Node)

<input> 태그 안에는 name, value 등의 속성을 사용할 수 있는데 이러한 속성(Attribute) 들을 가리키는 노드이다.

텍스트 노드 (Text Node)

태그 내 텍스트를 가리킨다. 텍스트 노드는 요소 노드(Element Node)의 자식이며

자신은 자식 노드를 가질 수 없기 때문에 DOM 트리의 최종단 이다.

<p> 텍스트!!! </p> 에서 ‘텍스트!!!’ 가 바로 텍스트 노드이다.

1. DOM 노드 취득(접근)

HTMLCollection과 NodeList

  • HTMLCollection과 NodeList는 DOM API가 여러 개의 결과 값을 반환하기 위한 DOM 컬렉션 객체이다.
  • HTMLCollection과 NodeList는 모두 유사 배열 객체면서 이터러블이다.
  • 따라서 for...of 문으로 순회할 수 있으며 배열로 변환할 수 있다.

HTMLCollection

  • getElementsByTagName, getElementsByClassName 메서드가 반환하는 객체이다.
  • 노드 객체의 상태 변화를 실시간으로 반영하는 살아있는(live) DOM 컬렉션 객체이다.
  • HTMLCollection 객체는 실시간으로 노드 객체의 상태 변경을 반영하여 요소를 제거할 수 있기 때문에 for문으로 순회하면서 노드 객체의 상태를 변경하는 경우 주의해야 한다.
    • 반복문 역방향 순회 혹은 while문 사용 등을 통해 회피할 수 있다.
    • 하지만 HTMLCollection 객체를 사용하지 않고 배열로 변환하는 것이 권장 된다.

NodeList

  • querySelectorAll 메서드가 반환하는 객체이다.
  • 실시간으로 노드 객체의 상태를 변경하지 않기(non-live) 때문에 HTMLCollection의 부작용을 해결할 수 있다.
  • NodeList 객체는 NodeList.prototype.forEach 메서드를 상속 받아 사용할 수 있다.
  • NodeList.prototype은 forEach 외에도 item, entries, keys, values 메서드를 제공한다.
  • 대부분의 NodeList는 non-live 객체로 동작하지만 childNodes 프로퍼티가 반환하는 NodeList 객체는 HTMLCollection 객체와 같이 실시간으로 노드 객체의 상태 변경을 반영하는 live 객체로 동작하므로 주의가 필요하다.

노드 객체의 상태 변경과 상관 없이 안전하게 DOM 컬렉션을 사용하려면 HTMLCollection이나 NodeList 객체를 배열로 변환하여 사용하는 것을 권장한다. 각각의 객체가 메서드를 제공하지는 하지만 배열의 고차 함수만큼 다양한 기능을 제공하지 않는다. 두 객체 모두 유사 배열 객체이면서 이터러블이므로 스프레드 문법이나 Array.from 메서드를 사용하여 간단하게 배열로 변환할 수 있다

배열로 변환하여 사용하는 것을 권장한다!!!!!!

굿.

2. DOM 노드 탐색

요소를 취득한 다음, 취득한 요소를 기점으로 DOM 트리의 노드를 옮겨다니며 부모, 형제, 자식 노드 등을 탐색(traversinig)해야 할 때가 있다.

DOM 트리 상의 노드를 탐색할 수 있도록 Node, Element 인터페이스는 트리 탐색 프로퍼티를 제공한다. ( 기능이 스레기 같아서 안쓰지만 )

노드 탐색 프로퍼티는 모두 참조만 가능한 읽기 전용 접근자 프로퍼티이다. 읽기 전용 접근자 프로퍼티에 값을 할당하면 아무런 에러 없이 무시된다.

child(자식) , parent(부모) , sibling(형제)

3. DOM 노드 수정

innerHTML

  • setter와 getter 모두 존재하는 접근자 프로퍼티로 요소 노드의 HTML 마크업을 취득하거나 변경한다.
  • textContent 프로퍼티는 HTML 마크업을 무시하고 텍스트만 반환하지만 innerHTML 프로퍼티는 HTML 마크업이 포함 된 문자열을 그대로 반환한다.

insertAdjacentHTML

  • Element.prototype.insertAdjacentHTML(position, DOMString) 메서드는 기존 요소를 제거하지 않으면서 위치를 지정해 새로운 요소를 삽입한다.
  • 첫번째 인수로 전달할 수 있는 문자열은 'beforebegin', 'afterbegin', 'beforeend', 'afterend'의 4가지이다.
  • insertAdjacentHTML 메서드는 기존 요소에 영향을 주지 않고 새롭게 삽입될 요소만을 파싱하여 자식 요소로 추가하므로 기존의 자식 노드를 모드 제거하고 다시 처음부터 새롭게 자식 노드를 생성하여 자식 요소로 추가하는 innerHTML 프로퍼티보다 효율적이고 빠르다. 단, HTML 마크업 문자열을 파싱하므로 크로스 사이트 스크립팅 공격에 취약하다는 점은 동일함

4. 노드 이동 교체 삭제

node insert move

node copy replace remove

요소 사이에 값을 넣고 싶을 때 !!!!!!!!!!!!!!!!!!!! 바로 그때가 되면 !!!!!!!!!!! 찾아보세요 .

5. 어트리뷰트 (속성)

attributes , getAttribute , setAttribute , hasAttribute , removeAttribute

6. 스타일

className ( 반환 문자열 ) , classList ( 반환 DOMTokenList ?? )

classList 메소드

add , item ( 0 ) , contains ,
replace(old , new) , toggle , remove

BOM (Browser Object Model, 브라우저 객체 모델)

BOM은 자바스크립트가 브라우저와 소통하기 위해서 만들어진 모델이다.

공식 표준은 아니지만 브라우저 대부분이 자바스크립트와의 상호작용에 있어서 비슷한 메소드와 속성으로 동작하기에 이와 같은 메소드들을 통칭하여 BOM 이라고 한다. Window객체를 통해 접근이 가능하다.

바로 F12 를 열어서 콘솔에 해당 메소드를 실행시켜 보면 엄청나게 많은 프로퍼티들을 볼 수 있다,

navigator , location , history , screen

EVENT ( 이벤트 )

표준 이벤트 모델

w3 에서 공식적으로 지정한 이벤트 모델. 한번에 여러개의 이벤트 핸들러 설정가능 IE 는 9버전부터 지원

[참고] HTML DOM 이벤트 종류

https://www.w3schools.com/jsref/dom_obj_event.asp

addEventListener ( type , listener() , option ) 인자 설명

type : 언제 (작동 원인) = 위에 있는 문서에 들어가면 종류가 정리되어있다.

자주 사용되는 type들

이벤트 명설명
change : 변동이 있을 때 발생

click : 클릭 시 발생

focus : 포커스를 얻었을 때 발생

keydown : 키를 눌렀을 때 발생

keyup : 키에서 손을 땟을 때 발생

load : 로드가 완료 되었을 때 발생

mousedown : 마우스를 클릭 했을 때 발생

mouseout : 마우스가 특정 객체 밖으로 나갔을 때 발생

mouseover : 마우스가 특정 객체 위로 올려졌을 때 발생

mousemove : 마우스가 움직였을 때 발생

mouseup : 마우스에서 손을 땟을 때 발생

select : option 태그 등에서 선택을 햇을 때 발생

출처:

https://chlolisher.tistory.com/10

[클로리셔 작은 공간:티스토리]

listner() : 무엇을 (취할 행동) = 호출할 함수

addEventListener ( type , listener() , option )

option 프로퍼티

option {
( capture 설명은 좀 자신이 없네요 false 와 useCapture 가 엄밀히 말하면 다른거같은데 
그냥 놓고 보면 똑같거든요)

capture : 이벤트 대상의 DOM 트리 하위에 위치한 자손 EventTarget으로 이벤트가 전달되기 전에,
 이 수신기가 먼저 발동돼야 함을 나타내는 불리언 값입니다. 
명시하지 않을 경우 기본 값은 false(useCapture)입니다. ( 본인부터 실행되고 부모를 실행함)
true  :   ( 최상위 부터 실행되고 자식을 실행함)

once : 수신기가 최대 한 번만 동작해야 함을 나타내는 불리언 값입니다. true를 지정할 경우, 
수신기가 발동한 후에 스스로를 대상에서 제거합니다. 명시하지 않을 경우 기본 값은 false입니다.

passive : true일 경우, 이 수신기 내에서 preventDefault()를 절대 호출하지 않을 것임을 
나타내는 불리언 값입니다.

}

preventDefault() 예제 문서

사용자의 행동을 방지하게 해주는 메소드이다.

https://developer.mozilla.org/ko/docs/Web/API/Event/preventDefault

 

이벤트가 발생한 해당 요소 객체에 접근하는 방법

+자바스크립트 this 가 무엇을 가리키는지…

<button id = "btn4">고전이벤트방식</button>
    <button onclick="test6();">인라인이벤트방식</button>
    <button id = "btn5">표준이벤트방식</button>

    <script>
        // 고전이벤트 방식 
        var btn4 = document.getElementById("btn4");
      
        btn4.onclick = function(e){//e 매개변수  : 발생한 이벤트 객체
            //MouseEvent객체
            console.log(e);           // PointerEvent 객체 정보
            console.log(window.event);  // PointerEvent 객체 정보

            //현재 이벤트가 발생한 요소에 대한 정보를 가져오고자 한다면 세가지 방법
            console.log(e.target);     // Element 요소 정보   (객체)
            console.log(window.event.target);    // Element 요소 정보   (객체)
            console.log(this);       // Element 요소 정보 (객체)

            e.target.style.color = "white";
            this.style.backgroundColor="red";
        }

        //인라인방식 -- 위 버튼에서 인라인으로 호출
        function test6(e){
            console.log(e);//매개변수로 이벤트 객체아는것은  불가능   undefined
            console.log(window.event.target); //정상    Element 요소 정보 (객체)
            console.log(this);// window 객체를 가리킴 (이벤트 객체를 아는 것은 불가능 )
        }

        //표준이벤트 방식 
        var btn5 = document.getElementById("btn5");
        btn5.addEventListener('click', function(e){
            console.log(e.target);     // Element 요소 정보 (객체)
            console.log(window.event.target);   // Element 요소 정보 (객체)
            console.log(this);   // Element 요소 정보 (객체)
        });

input type = submit 에게 이벤트를 만들어주면

이벤트를 우선 실행. return이 true 이면 그 다음 submit 실행. false 이면 submit 실행 안함

 

1. 클래스

클래스 , 익명클래스 , 기명클래스, 동적생성 클래스

생성 방법에 따라 이름을 나눠보았습니다

클래스

class Student{
    constructor(name){

        // 생성자는 1개이상 정의 될 수 없고 생략할 경우 암묵적으로 정의, 
        this.group = 1;
        this.name = name
        // 암묵적으로 this 반환 중
    }

    // 메소드
    introduce(){
        console.log(`저는 ${this.group}반 학생 ${this.name} 입니다!`);
    }
    // 암묵적으로 this 반환 하는 중 
    
}
//  결과 

console.log(new Student());            // constructor 실행 ,  Student { group: 1, name: undefined }
console.log(typeof Student);         // function
console.log(Student === Student.prototype.constructor);        // true
console.log(Student.prototype.introduce); // 클래스 내부에 정의한 메소드는 클래스, prototype에 저장 ,Array.prototype 처럼

익명클래스

// 1. 익명클래스 표현식     클래스 이름이 없으니까 생성자선언 + 바로사용 하는 용도 ??  (일회용)
let Tutor = class {
    teach(){
        console.log(`이해되시나요`);
    }
}
console.log('여기');
console.log(Tutor);       //  [class Tutor]
console.log(new Tutor());   //    Tutor {}
new Tutor().teach();    //   이해되시나요

기명클래스

// 2. 기명클래스 표현식
let Tutee = class MyTutee {
    learn(){
        console.log('이해 했습니다');
        console.log(MyTutee);   
    }
}

// console.log(MyTutee);      // 클래스 밖에서 사용불가
new Tutee().learn();     
//   이해 했습니다
//  [class MyTutee]

동적 생성 클래스

// 3. 클래스 동적 생성
function makeTutee(message) {  
    return class {
        feedback(){
            console.log(message);
        }
    }
    
}

let secondTutee = makeTutee("10점 맍점");
new secondTutee().feedback();       // 10점 맍점

get set

class Product{

    constructor(name, price){
        this.name = name;
        this.price = price;
    }

    get name(){
        console.log('get name동작');
        return this._name;   
        // 언더바를 붙이지 않으니 무한루프에 빠져버린다 .. 
        // this.name (언더바없음) 을 호출 할때 get (같은이름)의 함수가 호출된다고 한다. (작동원리)
        // 그래서 프로퍼티 이름을 일부러 다르게 써서 무한루프 방지를 한다.

    }

    get price(){
        console.log('get price동작');
        return this._price;  
    }

    set name(value){
        console.log('set name동작');
        this._name = value;  
    }
    set price(value){
        console.log('set price동작');
        if(value < 0){
            console.log('가격은 음수가 아닙니다');
            this._price = 0;
            return;
        }
        this._price = value;  
    }

}

// get은 프로퍼티를 읽으려 할 때   set은 프로퍼티에 값을 할당하려 할 때  자동으로 실행 됨

let phone = new Product('전화기', 23000);         // set 동작    음수처리 기능이 있다 !!!
console.log(phone.name + ',' + phone.price);           // get 동작

// 결과
set name동작
set price동작
get name동작
get price동작
전화기,23000

클래스 상속

class Animal{
    constructor(name, weight){
        this.name = name;
        this.weight = weight;
    }

    eat(foodWeight){
        this.weight = this.weight + foodWeight;
        console.log(`${this.name}(은)는 ${foodWeight}kg의 식사를 하고 ${this.weight}kg이 되었습니다.`);
    }

    move(lostWeight){
        if(this.weight > lostWeight)
        this.weight = this.weight - lostWeight;
        console.log(`${this.name}(은)는 움직임으로 인해 ${lostWeight}kg 감량되어 ${this.weight}kg이 되었습니다.`)
    }
}

let animal = new Animal('동물', 30);

animal.eat(1);   //  동물(은)는 1kg의 식사를 하고 31kg이 되었습니다.
animal.move(0.5);  //   동물(은)는 움직임으로 인해 0.5kg 감량되어 30.5kg이 되었습니다.

class Human extends Animal{

    develop(language){
        console.log(`${this.name}(은)는 ${language}로 개발을 합니다. 정말 즐겁습니다^.^`);
    }
}

let human = new Human('수강생', 70);

human.eat(2);    //   수강생(은)는 2kg의 식사를 하고 72kg이 되었습니다.
human.move(1);     //    수강생(은)는 움직임으로 인해 1kg 감량되어 71kg이 되었습니다.

human.develop('javascript') 
//    수강생(은)는 javascript로 개발을 합니다. 정말 즐겁습니다^.^

class Tiger extends Animal{
    attack(target){
        console.log(`${this.name}은 ${target}을 공격합니다`);
    }

    move(target){
        super.move(0.1);  // 부모 move 실행 
        this.attack(target);   // Tiger 만의 기능
    }
}

let tiger = new Tiger("호랭이", 90);
tiger.move('사슴');    
//   호랭이(은)는 움직임으로 인해 0.1kg 감량되어 89.9kg이 되었습니다.
//   호랭이은 사슴을 공격합니다

class Deer extends Animal{
    constructor(name, weight, leglength){
        super(name, weight); // 부모 생성자, 반드시 this 호출 전에 super 사용
        this.leglength = leglength;
    }

    hide(place){
        console.log(`${this.name} 은 ${place}에 숨습니다`);
    }
}

let deer = new Deer('사슴2', 100, 15);
deer.hide('나무밑');   //   사슴2 은 나무밑에 숨습니다

2. 화살표 함수 ( 보기 어려워 죽겠다 )

함수의 형식을 파괴해버리고

매개변수와 반환값만 적어주는 엄청 축약된 형태의 함수 입니다

(매개변수) ⇒ ( { 반환값 } ) ;

기본 구문 (MDN 문서 내용 중)

`(param1, param2, …, paramN) => { statements }
(param1, param2, …, paramN) => expression
// 다음과 동일함:  => { return expression; }

// 매개변수가 하나뿐인 경우 괄호는 선택사항:
(singleParam) => { statements }
singleParam => { statements }

// 매개변수가 없는 함수는 괄호가 필요:
() => { statements }`
// 객체 리터럴을 반환하는 경우 소괄호로 감싸주는것이 좋다.    
const createUser = (id, name) => ({id, name});
console.log(createUser(1,'이효리'));
//   { id: 1, name: '이효리' }

// 고차함수에 인수로 전달 가능하고 일반 함수 표현식 보다 간결하여 자주 사용
// map : 배열 요소 전체를 대상으로 콜백 함수 호출후 반환값들로 구성된 새로운 배열 반환
console.log([1,2,3,4,5].map(val => val * 10));
//   [ 10, 20, 30, 40, 50 ]    map 은 배열순회 함수

// 화살표 함수는 this를 가지지 않는다!!!!
// 객체 리터럴 (대문자가 아니니 생성자는 아님)
let theater = {
    store : '건대점',
    titles : ['어벤져스', '겨울왕국', '스파이더맨', '라이언킹', '알라딘'],

    // this는 자신의 상위를 뜻한다 ??
    // 외부에서 값을 가져온다 ?? 상위타입을 가져온다 ??

    // 일반함수에서의 this 는 전역(global) 을 가리킨다 ??

    // forEach : 배열 순회 함수
    showMovieList(){
        this.titles.forEach(
            title => console.log(this.store + ' : ' + title)
        );
    }
}

theater.showMovieList();
//  건대점 : 어벤져스
//  건대점 : 겨울왕국
//  건대점 : 스파이더맨
//  건대점 : 라이언킹
//  건대점 : 알라딘

// 화살표 함수는 new와 함께 호출할 수 없다

const arrowFunc = () => {};
// new arrowFunc();           //TypeError: arrowFunc is not a constructor
console.log(arrowFunc.hasOwnProperty('prototype')); //  false
console.log(arrowFunc.constructor);     // [Function: Function]

// 화살표 함수는 arguments 지원하지 않음    화살표함수 너무 보기힘드네요 무슨뜻일까요 이게
(function(){
    const arrowFunc = () => console.log(arguments);

    arrowFunc(3,4)
}(1,3));
//    [Arguments] { '0': 1, '1': 3 }

// 1,3 지우니까 출력이 안됨

MDN 문서 내용 중

화살표 함수는 자신의 arguments 객체가 없지만, 대부분의 경우에 나머지 매개변수가 좋은 대안입니다:

`function foo(n) { var f = (...args) => args[0] + n; return f(2); }

foo(1); // 3`

이전 예제를 '나머지 매개변수' 라는 좋은 대안으로 고친 코드

// 화살표 함수는 arguments 지원하지 않음    화살표함수 너무 보기힘드네요 무슨뜻일까요 이게
(function(){
    // const arrowFunc = () => console.log(arguments);
    const arrowFunc = (...args) => console.log(args);

    arrowFunc(3,4)   // 함수 실행을 하는 문장이긴한데 (위에 문장으로 실행하면) 매개변수 무시되고 있는듯
}(1,3));

// [ 3 , 4 ]

3. 심볼 (Symbol) 중요도 하

MDN 문서 내용 중

"심볼" 데이터 형식은 값으로 익명의 객체 속성(object property)을 만들 수 있는 특성을 가진 원시 데이터 형식(primitive data type)입니다

심볼  데이터 형식은 고도로 특화된 용도로 쓰이며, 범용성은 현저히 떨어집니다. 심볼 의 인스턴스에 L값(L-value)을 할당할 수 있고 식별자로 이용할 수 있습니다. 그게 전부입니다. 적용할 수 있는 연산자도 없습니다.

대놓고 쓰지 말라고 적어 놓은 듯한 데요. 허허허허허

중요하지 않은것 같으니 패스

//Symbol << 외부코드에서 접근 불가능 , 값도 덮어쓸 수 없는 숨김 프로퍼티를 만들 수 있다.

let student = {
    name : '홍길동'
}

let id = Symbol('id');
student[id] = 500; 

// student  [key] = value   로 프로퍼티 추가하는 문법
let name = 'name';
student[name] = '이대엽';

console.log(Object.keys(student));
console.log(student[id]);
console.log(student);

let student2 = {
    name : '홍길동',
    age : 15,
    [id] : 2 // 객체 리터럴 안에서 사용할 경우 대괄호를 사용해 심볼형 키를 만들 수 있다.
}

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
// 프로퍼티 이름 출력하는 반복문
for(let key in student2) console.log(key); // for in 반복문에서 키가 심볼인 경우 배제된다.
console.log(student2[id]);

console.log(Object.getOwnPropertySymbols(student));
console.log(Object.getOwnPropertySymbols(student2));

// 심볼은 유일무이하다 !!
let symbol1 = Symbol('mySymbol');
let symbol2 = Symbol('mySymbol');

console.log(symbol1 === symbol2);   // false

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);

// Symbol.for(key) 를 사용해 심볼을 전역 레지스트리에 만들고 읽는다. 
// 그래서 동일한 이름으로 존재하지 않으면 새로운 심볼을 만들고, 이름이 있다면 심볼을 다시 읽어온다

// 음 그래서 심볼의 용도가 무엇일까 ?????????   >>     나중에 찾아보기
let symbol = Symbol.for('id1');
let id1 = Symbol.for('id1');
console.log(symbol === id1);  // true

// 이름이 같더라도 값이 항상 다르므로 이름이 같을때 값도 같기를 원한다면 전역 레지스트리에 생성해서 사용해야함

4. 이터레이터 , 이터러블

/* 01_iterable (이터러블)
ES6 이전의 순회 가능한 데이터 컬렉션, 배열, 문자열, 유사 배열 객체, DOM 컬렉션 등은 
통일 된 규약 없이 for문, for...in문, forEach 메서드 등 다양한 방법으로 순회 할 수 있었다.

ES6에서는 순회 가능한 데이터 컬렉션을 이터레이션 프로토콜을 준수하는 이터러블로 통일하여 
for...of문, 스프레드 문법, 배열 디스트럭처링 할당의 대상으로 사용할 수 있도록 일원화했다.
*/  // 이터레이션 프로토콜

let range = {
    from : 1,
    to : 5
};

range[Symbol.iterator] = function () {
    return {
        current : this.from,
        last : this.to,

        // done : Iterator(반복자)가 마지막 반복 작업을 마쳤을 경우 true
        // value : Iterator(반복자)으로부터 반환되는 모든 자바스크립트 값
        next(){ // 인덱스마다 호출되는 함수
            if (this.current <= this.last){
                return {done : false , value : this.current++};     
            } else{
                return {done : true};
            }
        }
    }
}

// TypeError: range is not iterable
for(let num of range){
    console.log(num);
}

// 유사 배열 객체
let arrayLike = {
    0: '배열같은',
    1: '배열아닌',
    2: '배열이다',
    length : 3
}

// 배열 메서드 사용 불가
console.log(arrayLike);   
// { '0': '배열같은', '1': '배열아닌', '2': '배열이다', length: 3 }

console.log(typeof arrayLike);
//  object

// console.log(arrayLike.pop());

// 메서드는 유사 배열 객체(array-like object)나 
// 반복 가능한 객체(iterable object)를 얕게 복사해 새로운Array 객체를 만듭니다.
let arr = Array.from(arrayLike);
console.log(arr.pop());
// 배열이다

let arr2 = Array.from(range);
console.log(arr2);
//  [ 1, 2, 3, 4, 5 ]

// from 설명
// (iterable: Iterable<any> | ArrayLike<any>   ,     mapfn: (v: any, k: number) => any, thisArg?: any)
          // 이터러블 | 유사배열 ,  매개변수 => 리턴값                 화살표좀 작작써라!!!!!!!!!!   
let arr3 = Array.from(range, num => num * num);
console.log(arr3);
//  [ 1, 4, 9, 16, 25 ]

5. 스프레드 문법 ( 나머지 매개변수 ) [ …args]

// 스프레드 문법, 전개 문법

// max 안에는 숫자들만 들어갈 수 있다.
console.log(`가장 큰 값 : ${Math.max(10,20,30)}`); // 가장 큰 값 : 30

// max 안에는 배열은 들어갈 수 없다.
let arr = [10, 20, 30];
console.log(`가장 큰 값 : ${Math.max(arr)}`);   가장 큰 값 : NaN

// Spread!!!!!!!!!!!!!!!!!!!
console.log(`가장 큰 값 : ${Math.max(...arr)}`);  // 가장 큰 값 : 30

let arr1 = [10, 20, 30];
let arr2 = [100, 200, 300];

console.log(`가장 큰 값 : ${Math.max(...arr1, ...arr2)}`);    // 가장 큰 값 : 300
console.log(`가장 큰 값 : ${Math.max(...arr1, ...arr2, 500000)}`);
//  가장 큰 값 : 500000

let merged = [0, ...arr, 2, arr2]  //  (일부러 이상하게 합침)
console.log(merged);   //   [ 0, 10, 20, 30, 2, [ 100, 200, 300 ] ]

let str = "JavaScript";
console.log([...str]);
/**
[
  'J', 'a', 'v', 'a',
  'S', 'c', 'r', 'i',
  'p', 't'
]
*/

console.log(Array.from(str));
/**
[
  'J', 'a', 'v', 'a',
  'S', 'c', 'r', 'i',
  'p', 't'
]
*/

구조 분해 distructuring-assignment

MDN 문서 내용 중

구조 분해 할당  구문은 배열이나 객체의 속성을 해체하여 그 값을 개별 변수에 담을 수 있게 하는 JavaScript 표현식입니다.

 

배열 구조 분해

// 배열 구조 분해 할당

let nameArr = ['길동', '홍'];

// let firstName = nameArr[0]
// let lastName = nameArr[1]

let [firstName, lastName] = nameArr;

console.log(firstName);   // 길동
console.log(lastName);    //  홍

let [firstName2, lastName2] = '길 동'.split(' ');

console.log(firstName2);    //길
console.log(lastName2);     //동

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');
// 쉼표를 사용해서 필요하지 않은 배열요소는 버릴 수 있다
let [firstName3,      ,lastName3] = ['firstName', 'middleName', 'lastName'];
console.log(firstName3);        //firstName
console.log(lastName3);         //lastName

// 대입 연산자를 기준으로 우측에는 모든 이터러블 가능, 좌측에는 객체 프로퍼티도 가능
let user = {};
[user.firstName, user.lastName] = '길동 홍'.split(' ');

console.log(user.firstName);        //    길동
console.log('ㅡㅡㅡㅡㅡㅡㅡㅡkey valㅡㅡㅡㅡㅡㅡㅡㅡ');

//   entries  : Returns an array of key/values of the enumerable properties of an object
for(let [key,value] of Object.entries(user)){
    console.log(`${key} : ${value}`);
}
//    firstName : 길동
//    lastName : 홍

let student = '유관순';
let teacher = '홍길동';

[student, teacher] = [teacher, student];

console.log(`stu : ${student} ,tea : ${teacher}`);
//  stu : 홍길동 ,tea : 유관순

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡrestㅡㅡㅡㅡㅡㅡㅡㅡ');

let [sign1, sign2, ...rest] = ['양자리', '황소자리', '쌍둥이자리', '개자리',]
console.log(sign1);   //  양자리
console.log(sign2);    //    황소자리
console.log(rest);     //   [ '쌍둥이자리', '개자리' ]

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

let [firstName4 ='아무개', lastName4 = '김'] = ['길동'];
console.log(firstName4);    // 길동
console.log(lastName4);     //    김   (기본값으로 할당)

 

객체 구조 분해

// 객체 구조분해 할당

let pants = {
    productName : '팬츠',
    color : '검정색',
    price : 30000
}


let {productName, color, price} = pants;

console.log(productName);
console.log(color);
console.log(price);
/*
팬츠
검정색
30000
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');
let { color : co, price : pr, productName : pn } = pants;

console.log(co);
console.log(pr);
console.log(pn);
/*
검정색
30000
팬츠
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

let shirts = {
    productName : '베이직 셔츠'
}

// 초기값 할당 가능
let { productName : productName2 = '어떤상품', color : color2 = '어떤색상' , price : price2 = 0} = shirts;

console.log(productName2);
console.log(color2);
console.log(price2);

/*
베이직 셔츠
어떤색상
0
*/

console.log('ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ');

// pants 로 초기화 ????
let {productName : productName3} = pants;
console.log(productName3);   // 팬츠


let {productName : productName4, ...r} = pants;
console.log(productName4);
console.log(r.color);
console.log(r.price);

/*
팬츠
검정색
30000
*/

// 프로퍼티 값에 직접 그냥 할당하고 있음, 기본값도 할당하고
let productName5, color5, price5;
({productName : productName5 , color : color5 , price : price5 = 0} = pants);
console.log(productName5);
console.log(color5);
console.log(price5);

/*
팬츠
검정색
30000   (pants 에 30000이 있으니까 기본값 할당x )
*/


console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
// 중첩 구조 분해

let product = {
    size : {
        width : 10,
        height : 30
    },
    items : ['doll', 'robot']
};

let {
    size : {
        width,
        height
    },
    items : [item1, item2]          
} = product;   //  할당


// console.log(product.size.height);


console.log(width);
console.log(height);
console.log(item1);
console.log(item2);
/*
10
30
doll
robot
*/

console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
let {
    size , 
    items 
} = product;   // 할당

console.log(size.width);   // 10



// 함수의 매개변수에 적용
// 함수의 매개변수가 많거나 기본 값이 필요한 경우 활용, 순서도 고정되지 않아도 됨
// 구조분해 = 중괄호  {} 로 감싸주기가 중요
function displayProduct({producer = '아무개', width =0, height=0, items = []}) { 
    console.log(`${producer}, ${width}, ${height}`);
    console.log(items);
} ;
console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡ조금 이상하게ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);
displayProduct({width:'이대엽',producer: undefined, undefined, items:['Coffee', 'Donut']});
//  순서를 안맞게 해도 프로퍼티 값에 맞게 잘 들어가고있다.
//   아무개, 이대엽, 0
//    [ 'Coffee', 'Donut' ]


console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ`);  
// 객체 하나 임의로 생성
// 매개변수 순서가 맞지않아도 됨
let exProduct = {
    items : ['이효리', '도넛'],
    producer : '커피'
}

displayProduct(exProduct);
//  커피, 0, 0
//   [ '이효리', '도넛' ]

 

목차

상속

proto , prototype

배열

push , pop , indexof , lastindexof, includes , shift , unshift

slice , splice , reverse

배열 고차함수

sort, map , foreach , filter , concat , reduce , some , every

생성자함수 / 일반함수

//Object 생성자함수

const student = new Object();         // 빈 객체 생성

student.name = '이대엽';              // 프로퍼티 추가
student.age = 27;

console.log(student);
//결과
{ name: '이대엽', age: 27 }
// 생성자 함수 (리터럴 ?? ㅁㄹ)

const student1 = {            // 프로퍼티 값을 하나하나... 
    name : '이이대엽',
    age : 28,
    getInfo : function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}

const student2 = {            // 프로퍼티 값을 하나하나... (리터럴 단점)
    name : '22대엽',
    age : 22,
    getInfo : function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}

‘리터럴’ 은 변수에 할당하는 고정 형태의 값입니다.

int a 우항에 놓이는 1 int a = 1; var empty_object 우항에 놓이는 {} **var** empty_object = {} //빈 객체  와 같이 표기한 문자가 있는 그대로 자신을 나타내는 값이죠.

이것이 진짜 생성자 함수

// 리턴을 명시하지 않아도된다. 기본으로 빈 객체가 반환 된다 (고민? 좀 해볼만할지도)
// new 를 사용해서 함수를 호출했을때 이야기이다 !!!!!!!!!!! (암묵적인 return이 있다. )
// 일반함수처럼 사용하면 눈에 보이는대로 return이 없다.
// ( 첫글자를 대문자로 작성해야함. 작성자가 스스로 지켜야하는 컨벤션)
function Sstudent(name, age) {
    this.name = name;
    this.age = age;
    this.getInfo = function () {
        return `${this.name} 은 ${this.age} 살 입니다~`
    }
}
const sstudent = Sstudent('유재', 30);
// const sstudent = new Sstudent('유재', 30);
console.log(sstudent);

// 결과 
undefined
// 해석
new Sstudent(~~ ) 가 아닌 일반함수처럼 Sstudent(~~) 를 호출 했기 때문에
return 된게 아무것도 없기 때문이다.

target - new 연산자 없이 호출되는것을 방지하기 위해 지원하는 함수

function Dog(name, age) {
    // 일단 타겟이 뭐하는 넘인가?
    // new 연산자 없이 호출되는것을 방지하기 위해 지원하는 함수 (new.target)
    // 내부는 undefined 이다
    console.log(new.target);        // [Function: Dog]
    
    // 생성자목적으로 만들경우
    if(!new.target){
        return new Dog(name, age);
    }

    this.name = name;
    this.age = age;
}

const dog = Dog('ㅃㅃ', 3);
console.log(dog);

// 결과
[Function: Dog]
Dog { name: 'ㅃㅃ', age: 3 }

개발자의 실수를 방지하기 위해(?) 만들어진 함수라고 생각중 입니다

상속!!!!!!!!!!! (한 번도 써본적은 없음 )

const user = {
    activate : true,
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true
};

student.__proto__ = user;

console.log(student.activate);// 프로퍼티 activate를 student에서도 사용 가능
student.login();// 메소드 login도 student를 통해 호출 가능console.log(student.passion);

  • 'student의 프로토타입은 user이다.' 혹은 'student는 user를 상속 받는다.' 라고 한다.
  • 프로토타입에서 상속받은 프로퍼티를 상속 프로퍼티(inherited property)라고 한다.

내용이 너무 심오하다 …

그냥 아무 연관이 없는 객체 두 개를 만들고 뜬금없이 프로퍼티를 호출 하면 상속이 된다고하니 ..

아무 연관이 없는게 아니었다
__proto__ 라는 프로퍼티(key) 값에 user 라는 value 를 넣어서

student 는 user를 상속받는다 라는 선언이 되어있는것이었다.

  '        student.__proto__ = user;          '  바로 이 문장

 

const user = {
    activate : true,
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true
};

const greedyStudent = {
    class : 11,
    __proto__ : student       // set, get 역할을 한다?? student 만 바라보게 하는건가 ??
};

console.log(greedyStudent.activate);        // user에서 상속
console.log(greedyStudent.passion);         // student에서 상속
//결과 
undefined
true

student 객체 선언에 ' __proto__ : user ' 가 적혀 있었으면 undefined 안나왔음
const user = {
    id : 'user',
    login : function(){
        console.log(`${this.id}님 로그인 되었습니다.`);
    }
};

const student = {
    __proto__ : user
};

student.id = 'user01';
student.login();            // user01님 로그인 되었습니다.
  • 프로토타입은 프로퍼티를 읽을 때만 사용하며 프로퍼티를 추가, 수정, 삭제하는 연산은 객체에 직접 한다.
  • 메소드 내의 this는 프로토 타입에 영향받지 않으며 메소드를 객체에서 호출했든 프로토타입에서 호출했든 상관없이 this는 언제나 .앞에 있는 객체이다.

( . 앞에 있는 객체 = [student] . << 여기 앞 말하는듯? login() )

  • 메소드는 공유되지만 객체의 상태는 공유되지 않는다.

for...in문은 열거 가능한 non-Symbol 속성에 대해서만 반복합니다.

이것은 쉽게 객체의 속성을 확인(콘솔이나 다른 방법으로 출력)할 수 있기 때문에 실질적으로 디버깅을 위해 사용될 수 있습니다.

배열이 데이터의 저장에 있어서는 더 실용적이지만, 키-값 쌍이 선호되는 데이터의 경우(속성이 "key"의 역할을 함)

특정 값을 가진 키가 있는지 확인하려는 경우에 for...in을 사용할 수 있습니다

const user = {
    testprop : 'test1',
    activate : true,
    
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

const student = {
    passion : true,
    __proto__ : user
};

const greedyStudent = {
    class : 11,
    __proto__ : student       // set, get 역할을 한다?? student 만 바라보게 하는건가 ??
};
// ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ

for(let prop in greedyStudent) {
    console.log(`ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2`);
    console.log(prop);

    // key에 대응하는 프로퍼티가 상속 프로퍼티가 아니고 obj에 직접 구현되어있는 프로퍼티일 때만 true를 반환한다.
    let isOwn = greedyStudent.hasOwnProperty(prop);
    
    if(isOwn) {
        console.log(`객체 자신의 프로퍼티 ${prop}`);
        // greedyStudent.hasOwnProperty.
    } else {
        console.log(`상속 프로퍼티 ${prop}`);
    }
   
}
//결과 

ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
class
객체 자신의 프로퍼티 class
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
passion
상속 프로퍼티 passion
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
testprop
상속 프로퍼티 testprop
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
activate
상속 프로퍼티 activate
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ2
login
상속 프로퍼티 login

자신의 프로퍼티 순회 후  상속된 객체의 프로퍼티를 끝까지 순회 한다
키 값을 출력한다.  

함수형 프로토타입(상속)

const user = {
    activate : true,
    
    login : function(){
        console.log('로그인 되었습니다.');
    }
};

// 생성자 함수
function Student(name) {
    this.name = name;
}

// 여기서의 prototype은 일반적인 프로퍼티 (일반적인? 무엇이?.. 이해가 잘 안되었음)
// 프로토타입(상속) 을 정의

//const student = {
//    name : 'name',
//    __proto__ (= prototype) : user
//}; 
Student.prototype = user;               

let student = new Student("홍길동");    

console.log(student.activate);
//결과 ( user 의 activate 값 )
true
  • new 연산자를 사용해 만든 객체는 생성자 함수의 프로토타입 정보를 사용해 [[Prototype]]을 설정한다.
  • F.prototype은 new F를 호출할 때만 사용된다. new F를 호출할 때 만들어지는 새로운 객체의 [[Prototype]]을 할당한다.
function Student() {}
// 함수를 만들기만 해도 디폴트 프로퍼티인 prototype이 설정
// Student.prototype = { constructor: Student }
console.log(Student.prototype.constructor);
console.log(Student.prototype.constructor == Student);

let student = new Student();    // // {constructor: Student}을 상속받음
console.log(student.constructor == Student); // true ([[Prototype]]을 거쳐 접근함)
// 결과
[Function: Student]
true
true
  • 개발자가 특별히 할당하지 않더라도 모든 (생성자?)함수는 기본적으로 "prototype" 프로퍼티를 갖는다.
  • 디폴트 프로퍼티 "prototype"은 constructor 프로퍼티 하나만 있는 객체를 가리키는데, 여기서 constructor 프로퍼티는 함수 자신을 가리킨다.

이거는 이해하고 작성한건 아닙니다

느낌은 알겠음 하지만 논리적으로는 모르겠음

built in object prototype

 

const num = new Number(100);

// num은 Number.prototype을 상속받았는가?
console.log( num.__proto__ === Number.prototype ); // true

// num은 Object.prototype을 상속받았는가?
console.log( num.__proto__.__proto__ === Object.prototype ); // true

// 체인 맨 위엔 null이 있다.
console.log( num.__proto__.__proto__.__proto__ ); // null

// Number.prototype의 toString 사용
console.log(num);                  // [Number : 100]
console.log(num.toString());         // 100
    • Function, String, Number을 비롯한 내장 객체들 역시 프로토타입에 메서드를 저장한다.
    • 모든 내장 프로토타입의 상속 트리 꼭대기엔 Object.prototype이 있어야 한다고 규정한다.
    • Object.prototype에도 메서드 toString이 있다
    • 중복 메서드가 있을 때는 체인 상에서 가까운 곳에 있는 메서드가 사용된다.

 

배열 (자바스크립트의 배열)

// 1. 배열 리터럴을 통해 배열 생성
const arr = ['바나나', '복숭아', '키위'];

//전달된 인수값이 1개, 숫자 >> length 만큼 배열 생성
const arr3 = new Array(10);
console.log(arr3);  // [ <10 empty items> ]

// 인수값이 2개 이상이거나 , 숫자가 아닌경우 인수를 요소로 갖는 배열 생성
const arr4 = new Array(1,2,3,4,5);
console.log(arr4);  // [ 1, 2, 3, 4, 5 ]

// Array.of 메소드   =    전달 된 인수를 요소로 갖는 배열 생성
console.log(Array.of(10));   //  [ 10 ]
let testArr = Array.of(1,2,3);
console.log(testArr);   //  [ 1, 2, 3 ]

const arr6 = [1,2,3,4,5];
arr6.push(6);          // 마지막 인덱스로 값 추가
arr6.pop();              // 마지막 인덱스 제거 (원본 영향 o)

const sparse = [,2 , , 4];   // 구멍 숭숭 내도 만들어짐
console.log(sparse);        //[ <1 empty item>, 2, <1 empty item>, 4 ]
console.log(sparse.length);        // 4

console.log('프로퍼티 정보');
console.log(Object.getOwnPropertyDescriptors(sparse));

//결과 
{
  '1': { value: 2, writable: true, enumerable: true, configurable: true },
  '3': { value: 4, writable: true, enumerable: true, configurable: true },
  length: { value: 4, writable: true, enumerable: false, configurable: false }
}

'인덱스' : { 상세 정보 }
writable – true이면 값을 수정할 수 있다. 그렇지 않다면 읽기만 가능하다.
enumerable – true이면 반복문을 사용해 나열할 수 있다. 그렇지 않다면 
							반복문을 사용해 나열할 수 없다.
configurable – true이면 프로퍼티 삭제나 플래그 수정이 가능하다.

함수 메소드

indexof , lastindexof, includes

const foodList = ['물회', '삼계탕', '냉면', '수박', '물회'];

// indexOf  :  요소가 위치한 인덱스 반환
console.log(`foodList.indexOf('물회') : ${foodList.indexOf('물회')}`);       
// 0           

console.log(`foodList.indexOf('물회', 1) : ${foodList.indexOf('물회', 3)}`);  
//   n번 인덱스 이후로 검색      

console.log(`foodList.indexOf('삼겹살') :  ${foodList.indexOf('삼겹살')}`);    
// 없으면 -1 반환

// lastIndexOf  :  요소가 위치한 마지막 인덱스 반환
console.log(`foodList.lastIndexOf('물회') : ${foodList.lastIndexOf('물회')}`);     
     // 4

console.log(`foodList.lastIndexOf('물회', 1) : ${foodList.lastIndexOf('물회', 1)}`);
     // 0   n번 인덱스부터 0까지 거꾸로 찾는것같음

console.log(`foodList.lastIndexOf('삼겹살') : ${foodList.lastIndexOf('삼겹살')}`);  
    // 없으면 -1 반환

// includes 포함여부
console.log(`foodList.includes('물회') : ${foodList.includes('물회')}`);     
 // true          

console.log(`foodList.includes('삼겹살') : ${foodList.includes('삼겹살')}`);    
 // false

unshift , shift

//Array.prototype.unshift : 배열의 맨앞 요소 추가
//Array.prototype.shift : 배열의 맨앞 요소 제거 후 반환
const chickenList = ['양념치킨', '후라이드', '반반'];

chickenList.unshift('간장치킨');
console.log(chickenList);        // [ '간장치킨', '양념치킨', '후라이드', '반반' ]

chickenList.shift();
chickenList.shift();
chickenList.shift();
console.log(chickenList);         //[ '반반' ]

concat

// Array.prototype.concat : 두 개 이상의 배열을 결합
const idol1 = ['아이브', '오마이걸'];
const idol2 = ['트와이스', '에스파'];
const idol3 = ['블랙핑크', '레드벨벳'];

// 배열명.concat(배열명1, 배열명2, ...)
const mix = idol1.concat(idol2);
const mix2 = idol3.concat(idol1, idol2);

console.log(`idol1 기준으로 idol2 배열을 concat : ${mix}`);
// idol1 기준으로 idol2 배열을 concat : 아이브,오마이걸,트와이스,에스파

console.log(`idol3 기준으로 idol1, idol2 배열을 concat : ${mix2}`);
// idol3 기준으로 idol1, idol2 배열을 concat : 
//  블랙핑크,레드벨벳,아이브,오마이걸,트와이스,에스파
//  블핑 레드벨벳 트와이스는 ㅇㅈ

slice , splice , reverse

// Array.prototype.slice : 배열의 요소 선택 잘라내기
// Array.prototype.splice : 배열의 index 위치의 요소 제거 및 추가
const front = ['HTML', 'CSS', 'JavaScript', 'jQuery'];

//slice (시작인덱스, 종료인덱스)          1번에서 3번 앞에놈 까지 넥슬라이스
console.log(`front.slice(1,3) : ${front.slice(1,3)}`);  
console.log(front);

// splice (index, 제거수, 추가값)       3번 뒤에 1놈 자르고 "내용추가"
console.log(`front.splice(3,1,"react") : ${front.splice(3,1,"react")}`);
console.log(front);

// Array.prototype.reverse : 배열의 순서 뒤집기
console.log(`${[1,2,3,4,5].reverse()}`);

고차메소드

sort 를 사용하는 방법 - MDN 문서

https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Array/sort

그냥 sort 함수는 유니코드 기준으로 비교하기 때문에 숫자 비교에는 부적합한 함수다.......

sort

let numbers = [];

for (let i = 0; i < 10; i++) {
    numbers[i] = Math.floor(Math.random() * 100) + 1;      // 1부터 100까지 소수점 다 버리기?
    
}

// 무작위 난수 생성    정렬 드가자 !!!

function compare(a,b) {
    if(a > b) return 1;
    if(a == b) return 0;
    if(a < b) return -1;
}

// sort 함수의 인자로 반환값이 1, 0 , -1 인 정렬함수를 이용해야한다.
// MDN 에게 물어보세요
numbers.sort(compare);                
console.log(`정렬 후 : ${numbers}`);

//     function(a,b) return b - a;   ( 양수값이면 a>b 음수값이면 a<b 라는 뜻)
numbers.sort((a,b) => b - a );
console.log(`내림차순 : ${numbers}`);

//     function(a,b) return a - b;   ( 양수값이면 a>b 음수값이면 a<b 라는 뜻)
numbers.sort((a,b) => a - b );
console.log(`오름차순 이해완료 : ${numbers}`);

foreach

numbers = [1,2,3,4,5];

numbers.forEach(function (item, index, array) {
    // 배열의 요소에 각각 실행할 기능을 작성, 각 요소에 대해 콜백을 실행, 배열을 순회하기때문에 break 사용 불가
    // 반환값 없음  , 배열 전용 함수이군요
    
    console.log(`item : ${item}`);
    console.log(`index : ${index}`);
    console.log(`array : ${array}`);
})

결과

item : 1
index : 0
array : 1,2,3,4,5

item : 2
index : 1
array : 1,2,3,4,5

item : 3
index : 2
array : 1,2,3,4,5

item : 4
index : 3
array : 1,2,3,4,5

item : 5
index : 4
array : 1,2,3,4,5

map

// Array.prototype.map  : 배열 요소 전체를 대상으로 콜백 함수 호출후 
//   반환값들로 구성된 새로운 배열 반환

//                                매개변수    return 값
const types = [true, 1, 'text'].map(item => typeof item);
console.log(`types : ${types}`);

//                                                         매개변수    return 값
const lengths = ['apple', 'banana', 'cat', 'dog' , 'egg'].map(item => item.length);
console.log(`length : ${lengths}`);

// 결과 
types : boolean,number,string 
length : 5,6,3,3,3 

filter

// Array.prototype.filter  : 배열 요소 전체를 대상으로 콜백 함수 호출후 
//          반환값이 true인 요소로만 구성된 새로운 배열 반환 // 원본에 영향 x

numbers = [1,2,3,4,5];

//                         매개변수    return 값
const odds = numbers.filter(item => item % 2);

console.log(odds);
console.log(numbers);    // 원본에 영향 x

// 결과
[ 1, 3, 5 ]
[ 1, 2, 3, 4, 5 ]

reduce ★★★★★★ 잠재력이 많은 함수인듯…

 

‘배열을 순회하며 ‘

각 요소에대해 이전의 콜백함수 실행 반환값을 전달하여 콜백함수를 실행하고 그 결과를 반환

 

(method) Array<number>.reduce(callbackfn:

(previousValue: number, currentValue: number, currentIndex: number, array: number[]) => number)

// Array.prototype.reduce  : 
//    배열을 순회하며 각 요소에대해 이전의 콜백함수 실행 반환값을 
//    전달하여 콜백함수를 실행하고 그 결과를 반환

numbers = [1,2,3,4,5];

numbers.reduce(function (preValue, curValue, curIndex, array) {
    console.log(`preValue : ${preValue}`); // 이전 콜백의 반환 값
    console.log(`curValue : ${curValue}`); // 배열 요소의 값
    console.log(`curIndex : ${curIndex}`); // 배열 요소의 인덱스
    console.log(`array : ${array}`); // 메소드를 호출한 배열
}   
// 이부분에 추가로 인자를 작성할 수 있다.
// 초기 값
);

reduce 합산

// 합산
numbers = [1,2,3,4,5];
const sum = numbers.reduce(function (preValue, curValue) {
    console.log(`pre : ${preValue}, cur : ${curValue}`);

    return preValue + curValue;
});

console.log(`sum : ${sum}`);

// 결과
pre : 1, cur : 2
pre : 3, cur : 3
pre : 6, cur : 4
pre : 10, cur : 5
sum : 15

reduce 최대값

//최대값
numbers = [1,2,3,4,5];
const max = numbers.reduce(function(preValue, curValue){

        return preValue > curValue ? preValue:curValue;       
})
console.log(max);   // 5

some

배열 내 ‘일부’ 요소가 콜백 함수의 테스트를 통과하는지 확인하여 그 결과를 boolean 으로 반환

// Array.prototype.some : 

// 화살표 함수 좀 안썼으면 좋겠다 !!!!!!!!!!!
let result = [1,5,2,3,4].some(item => item > 10);
console.log(`result : ${result}`);      //    result : false

let result1 = [1,5,2,3,4].some(item => item > 3);
console.log(`result1 : ${result1}`);    //    result1 : true

result = ['apple', 'banana', 'cat', 'dog'].some(item => item === 'egg')

console.log(`result : ${result}`);     //    result : false

▼ 약간 SQL문의 ANY , ALL 느낌 △

                                          some               every

 

every

배열 내 ‘모든’ 요소가 콜백 함수의 테스트를 통과하는지 확인하여 그 결과를 boolean으로 반환

// Array.prototype.every  : 
result = [1,5,2,3,4].every(item => item > 3);
console.log(`result : ${result}`);        //   result : false


result1 = [1,5,2,3,4].every(item => item > 0);
console.log(`result : ${result1}`);        //      result : true

 

 

 

DOM이란 무엇인가?

  • Document Object Model = 문서 객체 모델
  • HTML 요소를 자바스크립트 객체(Object)처럼 조작할 수 있게 만든 모델/구조
  • 즉, DOM을 이용해서 HTML로 구성된 웹페이지를 동적으로 움직이게 만들 수 있다

w3school.com   

 

Mega site of Bible Information

You can write to us at BIBLE DESK, P.O. BOX 11106, ST PETERSBURG, FL 33733. We want to help. We confess that Jesus Christ is come in the flesh. It is written, Hereby know ye the Spirit of God: Every spirit that confesseth that Jesus Christ is come in the f

w3school.com

 

 

https://developer.mozilla.org/ko/docs/Web/JavaScript

 

JavaScript | MDN

JavaScript (JS)는 가벼운, 인터프리터 혹은 just-in-time 컴파일 프로그래밍 언어로, 일급 함수를 지원합니다. 웹 페이지를 위한 스크립트 언어로 잘 알려져 있지만, Node.js, Apache CouchDB, Adobe Acrobat처럼

developer.mozilla.org

JavaScript Reference

Properties and Methods of all JavaScript Objects

모든 자바스크립트 객체의 속성(Properties)과 함수들(Methods)

 

 

HTML DOM Reference

Properties and Methods of all DOM Objects

모든 DOM 객체의 속성(Properties)과 함수들(Methods)

 

 

 

 

특히 MDN 이 자신이 객체, 인스턴스, 배열, 반환값, 등등.. 용어 정리만 되어있다면 진짜 미친듯이 도움 많이 되는 

문서입니다.

 

바닐라 JS 공부를 열심히 합시다

클라이언트 >> 브라우저(뷰) >> Request (Controller) (자바프로그램) >> DB

클라이언트 << 브라우저(뷰) << Response << DB

 

 

 

document.getElementById(”아이디명”)

 


자바스크립트의 변수, 데이터 타입

원시 타입의 불변성 (immutable)

자바스크립트에서 원시 타입은 변수에 할당될 때 메모리에 고정 크기로 원시 값을 저장하고 그 값을 변수가 직접 가리키는 형태를 띈다.

즉 데이터를 저장하기 위한 별도의 데이터 공간을 확보해 값을 저장하고, 그 공간을 변수 영역에 저장한다.

➡️ 변수 영역과 데이터 영역이 존재 <<<<<<< 기억!!!!!!!!!!!

 

이렇게 할당된 값은 **불변성(immutable)**을 갖는다.즉 메모리에 할당된 원시 타입의 값은 그 자체가 변경될 수 없다. ( 메모리 주소가 변경되는 것이다 )

이에 대해 조금 더 자세히 설명해 보자면, 변수에 값을 재 할당할 때 기존 값이 변하는 것처럼 보이지만 사실은 새로운 메모리에 재 할당한 값이 저장되고 변수가 가리키는 메모리가 달라지는 것이다.

 

 

string 의 주소값이 계속 바뀌면서 '새 메모리 값'이 저장되고 있다는 말 .

(사진 속 주석의 의미가 조금 모호해서 이걸로 이해하기 바람)

 

 


메모리의 개념은 자꾸 자꾸 말해도 어렵고 중요한 내용이라 중복이지만 또 작성하겠습니다

변수 영역과 데이터 영역이 따로 존재합니다. (중요, 기억)

 

변수 영역에는 변수의 이름과 데이터의 ‘주소값’ 만 들어있습니다.

 

데이터 영역의 주소값 에는

@5004 >> ‘abc’

@5005 >> ‘abcdef’

이 저장되어있고

 

let a = ‘abc’;

@5004 가 저장되어있던 변수 a 에 ‘abcdef’ 값을 재 할당 하려고 하면,

a = ‘abcdef’;

변수 a 의 메모리 주소가 @5005 로 교체가 됩니다.

 


 

불변값 (Immutable Value)

  • 변수와 상수를 구분 짓는 요소 : 변수 영역 메모리의 변경 가능성
  • 불변성 여부를 구분 짓는 요소 : 데이터 영역 메모리의 변경 가능성
  • 기본형 데이터(Number, String, Boolean, Null, Undefined, Symbol)들은 모두 불변값

원시 타입에 속하는 데이터 타입에는

숫자(Number & Bigint)

문자열(String)

논리형(Boolean)

null, undefined

심볼(Symbol) 이 있다.

참조 타입 (Reference Type)

자바스크립트에서 원시 타입을 제외한 나머지는 참조 타입**(객체, Object)**이라 할 수 있다.

참조 타입과 원시 타입의 가장 큰 차이점은, 객체의 변수(프로퍼티) 영역이 추가로 존재 한다는 것이다.

  • 기본형 데이터와 차이는 '객체의 변수(프로퍼티) 영역'이 별도로 존재하는 점
  • 데이터 영역에 저장 된 모든 값은 불변값
  • 변수 영역에 저장 된 값은 가변값
  • 불변값이 들어가야 되는 데이터영역에 가변값을 갖는 객체 프로퍼티 주소를 가지고 있기 때문에 참조형 데이터는 가변한다고 표현

 

 

 

위에 적은 설명으로 대체합니다 … ..

  • 데이터 영역에 저장 된 모든 값은 불변값
  • 변수 영역에 저장 된 값은 가변값
  • 불변값이 들어가야 되는 데이터영역에 가변값을 갖는 객체 프로퍼티 주소를 가지고 있기 때문에 참조형 데이터는 가변한다고 표현


 

 

 


 

 

 

 

 

 

~ = >> 문자열 포함

| = >> - 로 구분되는 단어 기준으로 일치

^ = >> 특정 값으로 시작하는 태그 ( name 이면 n 만 입력해도 적용 )

$ = >> 특정 값으로 끝

*= >>> 특정 값 포함

 

지금보니까 정규표현식이랑 문법이 비슷하군요

 

 

 

div>h4 { }

div ul { } ( ul 하위 선택자들 모두 적용 )

div li { } ( 후손에게 바로 접근 가능 )


 

 

 

 

 

선택자{ text-shadow:none|가로거리 세로거리 번짐정도 색상; }

 

하이퍼링크 밑줄 없애기   text-decoration : none;

 

 

 

 

 

 

 

+ Recent posts