1. M/D/YYYY -> YYYYMMDD

- 월/일 1자리 숫자가올때 '0' 붙여서 처리하기

 

2. try catch

- 함수 처리할때 catch(err)부분은 조건문에 throw 처리하기

 

3. 태그 삭제 구현

? parentNode, removeChild, addEventListener

 

4. 특정 태그에 스타일 추가

 

'Javascript' 카테고리의 다른 글

[Javascript] 실행 컨텍스트  (0) 2021.07.20
[Javascript] this  (0) 2021.07.09
[Javascript] 스코프(Scope)  (0) 2021.07.08
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03

실행 컨텍스트(Execution Context / EC)

- 실행 코드에 제공할 정보들을 모아 놓은 객체

- 자세히 설명하자면 코드를 실행하기 위해서는 여러가지 정보를 알고 있어야 한다.

  • 변수 : 전역변수, 지역변수, 매개변수, 객체 프로퍼티
  • 함수
  • 변수의 유효범위(Scope)
  • this

- 위와 같은 정보들을 형상화하고 구분하기 위해 실행 컨텍스트를 객체의 형태로 관리한다.

- 전역 코드로 컨트롤이 진입하면 가장 먼저 전역 실행 컨텍스트가 생성되고 애플리케이션이 종료될 때 까지 유지된다.

실행 컨텍스트의 3가지 객체

1. Variable Object(VO / 변수객체)

- Variable Object는 실행 컨텍스트의 프로퍼티이기 때문에 값을 갖는데 이 값은 다른 객체를 가리킨다.

- Variable Object는 전역 컨텍스트와 함수 컨텍스트가 있는데 가리키는 객체가 다르다.

  • 변수
  • 매개변수(Parameter), 인수(arguments)
  • 함수 선언문(함수 표현식 제외)

전역 컨텍스트와 함수 컨텍스트 차이점

전역 컨텍스트 : 전역 객체(Global Object / GO)를 가리키고 전역 변수, 전역 함수를 프로퍼티로 갖는다.

함수 컨텍스트 : 활성 객체(Activation Object / AO)를 가리키고 매개변수, 인수들의 정보(arguments object)를 갖는다.

2. Scope Chain(SC) 

- 스코프 체인(Scope Chain)이란 전역 객체 및 함수의 스코프를 차례대로 저장하는 것이다. 

- 스코프 체인을 통해 렉시컬 스코프를 접근한다.

만약 (전역변수 - 부모함수 - 자식함수) 이러한 실행컨텍스트 스택이 쌓였을 경우

자식함수 실행 컨텍스트에서 전역변수를 검색한다면

  1. 활성 객체(AO)를 시작으로 - (자식함수)
  2. 상위 컨텍스트 활성 객체(AO) - (부모함수)
  3. 전역 객체(GO)까지 검색하여 변수를 찾는다.

위처럼 순서대로 검색을 이어가기 때문에 이것을 스코프 체인이라고 불른다.

3. this value

this프로퍼티에는 this 값이 할당되고 this 값은 함수 호출 패턴에 의해 결정된다.

실행 컨텍스트 스택 생성 소멸

- 스택은 LIFO(Lats In First Out, 후입선물)의 구조를 가진다.

- 전역 실행 컨텍스트는 애플리케이션이 종료될 때까지 유지된다.

 

1. 전역 코드가 실행 컨텍스트 스택에 쌓인다.

2. 부모 함수를 호출하면 부모함수가 스택에 쌓인다.

3. 자녀 함수를 호출하면 자녀함수가 스택에 쌓인다.

4. 자녀함수 실행이 끝나면 해당 함수의 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트를 반환한다.

5. 부모함수 실행이 끝나면 해당 함수의 실행 컨텍스트를 파기하고 직전의 실행 컨텍스트를 반환한다.

    var global = '전역 코드';
    function parent() {
        var parent = '부모 함수';
        function child() {
            var child = '자녀 함수';
        }
        child();
    }
    parent();
    
    //     컨텍스트 생성
    //     1. 전역 변수 
    //     2. 전역 변수 parent()함수
    //     3. 전역 변수 parent()함수 child()함수

    //     컨텍스트 소멸
    //     1. 전역 변수 parent()함수
    //     2. 전역 변수

실행 컨텍스트 생성 과정

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}

foo();
변수 객체화(Variable Instantiation)
- 변수 객체화는 해당 실행 컨텍스트 변수 객체에 프로퍼티와 값을 추가하는 것을 의미한다.
전역 실행 컨텍스트 : 전역 객체(전역 변수, 전역 함수) GO를 가리킴
함수 실행 컨텍스트 : 변수, 매개변수, 인수 정보(arguments), 함수 선언을 VO에 추가하여 객체화 

변수 객체화 순서
1. (함수 코드) 매개변수가 VO의 프로퍼티, 인수가 값으로 설정
2. 함수명이 VO의 프로퍼티, 생성된 함수 객체가 값으로 설정(함수 호이스팅)
3. 변수명 VO의 프로퍼티, undefined 값으로 설정(변수 호이스팅)

(실행 컨텍스트 실행 과정)

  1. 스코프 체인 생성과 초기화
  2. Variable Instantiation(변수 객체화)실행
  3. this value 결정

전역 코드에 진입

1. 실행 컨텍스트에 진입하기 전에 유일하게 전역 객체가 생성된다.(빌트인 객체-Math, String, Array, BOM, DOM)

2. 전역 실행 컨텍스트가 생성되고 실행 컨텍스트 스택에 쌓인다.

3. 전역 실행 컨텍스트

3.1 전역 실행 컨텍스트는 가장 먼저 스코프 체인의 생성과 초기화를 실행하고, 전역 객체를 포함한다.

3.2 변수 객체화 실행 -> 변수, 함수 매개변수, 인수 정보 등을 변수 개체에 추가하여 객체화

  3.2.1 함수 foo 선언 처리

    - foo함수 객체는 [[Scope]]프로퍼티를 가지게 된다.

    - 이때 내부 프로퍼티는 foo함수 객체가 실행되는 환경을 가리킨다.

    - foo함수의 [[Scope]]는 자신의 실행 환경과 자신을 포함하는 외부 함수 실행 환경과  전역객체를 가리키고

    - 외부 함수의 실행 컨텍스트가 소멸하여도 [[Scope]]가 가리키는 외부 함수의 실행 환경은 소멸하지 않고 참조할 수 있다.

    - 이것을 클로저라고 한다.

 

(지금 까지 실행 컨텍스트는 아직 코드가 실행되기 이전이다.)
이때 함수 호이스팅 현상이 발생하게 된다.

스코프 체인이 가리키는 변수 객체(VO)에 이미 함수가 등록되어 있기 때문에
코드를 실행할 때 함수 선언식 이전에 함수를 호출할 수 있게 된다.

 

 

 

 

'Javascript' 카테고리의 다른 글

간단한 정리  (0) 2021.07.28
[Javascript] this  (0) 2021.07.09
[Javascript] 스코프(Scope)  (0) 2021.07.08
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03

this 바인딩 vs 렉시컬 스코프

- this : 함수를 호출할 때 함수가 어떻게 호출 되었는지에 따라 this에 바인딩할 객체가 동적으로 결정됌

- 렉시컬 스코프 : 함수를 어디에 선언하였는지에 따라 상위 스코프가 결정된다.

 

this 호출 방식

- 함수 호출

- 메소드 호출

- 생성자 함수 호출

- apply, call, bind 호출

    function test() {
        console.dir(this)
    }
    
    // 1. 함수 호출
    test(); // window
    
    // 2. 메소드 호출
    var obj = {test:test};
    obj.test(); // obj
    
    // 3. 생성자 함수 호출
    var instance = new test(); // instance
    
    // 4. apply, call, bind 호출
    var a = { name: 'apply, call, bind 메소드 호출'}
    test.call(a); // a
    test.apply(a); // a
    test.bind(a)(); // a

- 4가지 방법 모두 test() 함수를 호출하였지만 this가 바인딩한 객체는 다르다 

1. 함수 호출 : window (this는 전역 객체에 바인딩된다.)

2. 메서드 호출 :  obj (함수가 객체의 프로퍼티 값일때는 메소드로 호출되는데 이때 this는 해당 메소드를 소유한 객체에 바인딩된다.)

3. 생성자 함수 호출 : new 연산자로 생성하였기 때문에 instance 변수에 객체(Person)를 반환한다. 

4.

 

1. 함수 호출

1. 기본적으로 this는 전역객체에 바인딩 된다.

2. 전역객체는 전역 스코프를 갖는 전역변수를 프로퍼티로 갖는다.

3. 전역에서 선언한 함수에서 this는 전역객체의 프로퍼티로 접근 할 수 있는 전역 변수의 메소드이다.

4. 내부함수(자식함수)는 어디에서 선언되었든 상관없이 this는 전역객체를 바인딩한다.

  - 그 이유는 메소드, 외부함수(부모함수)가 내부함수를 사용하여 자신의 작업을 돕게 할수 없게 만들어졌기 때문이다.

일반적인 함수에서 호출한 this

    var a = '전역 변수';
    function b() {
        console.log('전역 함수');
    }
    
    console.log(window.a); // 전역 변수
    console.log(window.b()); // 전역 함수

내부 함수와 외부 함수에서 호출한 this

- 내부 함수의 경우 this를 호출 할경우 외부 함수 객체를 바인딩 할거 같지만,

- 내부 함수와 외부 함수의 this는 모두 전역 객체를 바인딩한다.

    var name = "전역 변수"
    
    function a() {
        var name = "외부 함수";
        function b() {
            console.log(this.name);
        }
        console.log(name); // 외부 함수
        console.log(this.name); // 전역 변수
        b(); // 전역 변수
    }
    
    a();

2. 메소드 호출

- 함수가 객체의 프로퍼티 값일때 메소드로 호출된다.

- 이때 메소드 내부의 this는 해당 메소드를 소유한 객체에 바인딩된다.

메소드에서 this를 호출할 때

    var name = "전역 변수";
    var obj = {
        name : "obj객체 변수",
        callName : function() {
            console.log(this.name);
        }
    }
    
    console.log(this.name) // 전역 변수
    obj.callName() // obj객체 변수

메소드에서 내부 함수를 호출할 때

    // parent 함수에서 this는 obj객체 변수(name)를 바인딩한다.
    // inner 함수에서 this는 전역객체 변수(name)를 바인딩한다
    
    var name = "전역 변수";
    var obj = {
        name : "obj객체 변수",
        parent : function() {
            var name = "외부함수 변수"
            function inner() {
                console.log(this.name)
            }
            console.log(this.name); // obj객체 변수
            inner(); // 전역 변수
        }
    }
    
    obj.parent();

 

3. 생성자 함수 호출

생성자 함수 : 기존 함수에 new연산자를 작성하여 호출하면 생성자 함수로 작동한다.

생성자 함수 this 바인딩 방식

1. new 연산자를 통해 작성된 생성자 함수에 빈 객체가 생성된다.

2. 생성자 함수 내에서 사용되는 this는 1번의 빈 객체를 가리킨다.

3. 생성된 빈 객체 에서는 this를 사용하여 동적으로 프로퍼티 or 메소드를 생성할 수 있다. 

생성자 함수 new 연산자 붙이고 호출

- 생성자 Person함수 this는 빈객체를 가리키기 때문에 전역객체를 바인딩 못함

- new 연산자로 생성하였기 때문에 me 변수에 객체(Person)를 반환한다. 

    var name2 = 'ss'
    
    function Person(name) {
        console.log(this.name2); // undefined
        console.log(this.name); // undefined
        console.log(name); // Lee

        this.name = name;
        
        console.log(this.name) // Lee
    }
    
    var me = new Person('Lee');
    console.log(me); // Person {name: "Lee"}

생성자 함수 new 연산자 붙이지 않고 호출

- 생성자 함수를 new 연산자 없이 호출할 경우 this는 전역객체를 가리켜서 전역변수가 바인딩 된다.

- new 연산자없이 생성하였기 때문에 호출할 경우 반환문이 없어 undefined를 반환한다.

    var name2 = 'ss'
    
    function Person(name) {
        console.log(this.name2); // ss
        console.log(this.name); // 공백(빈 객체여서 this.name을 못찾는거 같음 or undefined인데 오류인듯) 
        console.log(name); // Lee

        this.name = name;
        
        console.log(this.name) // Lee
    }
    
    var me = Person('Lee');
    console.log(me); // undefined

 

4. apply/call/bind 호출

'Javascript' 카테고리의 다른 글

간단한 정리  (0) 2021.07.28
[Javascript] 실행 컨텍스트  (0) 2021.07.20
[Javascript] 스코프(Scope)  (0) 2021.07.08
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03

스코프(Scope)

- 변수에 접근할 수 있는 범위

스코프 종류

전역 스코프(Global scope)

- 코드 어디에서든 참조 가능

지역 스코프(Local scope)

- 함수 코드 블록 안에서 만든 스코프로 함수 자신과 자식 함수에서만 참조 가능

    var global = '전역 스코프';
    function test() {
        var local = "지역 스코프";
        console.log(`${local} 호출`)
    }
    
    console.log(`${global} 호출`); // (1) 전역 스코프 호출
    console.log(`${local} 호출`) // (2) local is not defined
    test() // (3) 지역 스코프 호출
             // 지역 스코프는 함수 내부에서 접근 가능하다
            // (2)과 같이 지역 스코프는 함수 외부에서 접근 불가능하다.

자바스크립트 스코프 특징

블록 레벨 스코프(block-level scope)

- 코드 블록( {...} )내에서 접근 가능한 스코프(조건문, 반복문, while, try/catch 등)

- 자바스크립트를 제외한 타 언어(C언어, Java언어)들은 블록 레벨 스코프를 따른다.

- 단 ES6에서 도입된 let keyword는 블록 레벨 스코프를 따른다.

    // 블록 레벨 스코프 예제
    
    // (1) 블록 코드 안에서 변수 선언
    {
        var a = 100;
    }
    // (2) 반복문 코드 안에서 변수 선언
    for(var i=0; i<10; i++) {
        
    }
    
    console.log(a); // 100
    console.log(i); // 10

(1), (2) 과 같이 변수를 블록 내부에서 선언하여 타 언어에 경우에는 블록 레벨 스코프에서만 접근이 가능하지만

자바스크립트는 함수 레벨 스코프를 따르기 때문에 블록 외부에서 접근이 가능하다.

함수 레벨 스코프(function-level-scope)

- 함수 코드 블록 내에서 선언된 변수는 함수 내부에서만 접근 가능하고 외부에서는 접근 불가능하다.

- 자바스크립트는 함수 레벨 스코프를 따른다.

1. 기본 예제)

    var a = 10;
    function test() {
        var b = 20;
    }
    
    console.log(a) // 10
    console.log(b) // b is not defined

2. 참조 순위 예제)

    // a변수 스코프 범위
    // 전역 > 부모 함수 > 지역 함수
    // 이 중에서 중복 a변수를 호출하면 가까운 곳에서 참조한다 (단 함수 외부에서 호출할 경우 전역변수를 참조)
    
    // (1) 부모 함수에서 a변수를 호출하면 전역 변수가 아닌 부모함수에서 선언한 a를 참조
    // (2) 자식 함수에서 a변수를 호출하면 가장 가까운 스코프를 참조 하기 때문에 부모함수에서 선언한 a를 참조
    // (3) 함수 레벨 스코프 특성으로 부모함수에서 선언한 변수를 참조하지 못하고 전역변수를 참조
    
    var a = 'global';
    
    function outer() {
        var a = 'local';
        console.log(a); // (1) local
        
        function inner() {
            console.log(a); // (2) local
        }
        
        inner();
    }
    
    outer();
    console.log(a); // (3) global

3. 변수값 변경 예제)

    // 함수 영역에서 전역변수를 참조 할 수있어서 값 변경이 가능하다
    // 또한 자식 함수에서도 부모 함수 or 전역 변수를 참조하여 변경이 가능하다
    
    var a = '전역';
    
    function outer() {
        console.log(a) // (1) 전역
        a = '부모 함수';
        console.log(a); // (2) 부모 함수
        
        function inner() {
            a = '자식 함수';
            console.log(a); // (3) 자식 함수
        }
        
        inner();
    }
    
    outer();
    console.log(a); // (4) 자식 함수

let vs var 스코프 차이점

- let : 블록 레벨 스코프를 따른다.

- var : 함수 레벨 스코프를 따른다.

    // var는 함수 레벨 스코프를 따르기 때문에 {} 안에 변수를 선언했지만 {} 외부에서 접근 가능
    // let은 블록 레벨 스코프를 따르기 때문에 {} 안에 변수를 선언하면 {} 외부에서 접근 불가능
    
    var a = 1;
    {
        var a = 2;
        console.log(a); // 2
    }
    
    let b = 10;
    {
        let b = 20;
        let c = 30;
        console.log(b); // 20
        console.log(c); // 30
    }
    
    console.log(a); // 2
    console.log(b); // 10
    console.log(c); // c is not defined

렉시컬 스코프

- 함수를 어디서 호출하였는지가 아니라 어디에 선언하였는지에 따라 상위 스코프가 결정된다.

- 자바스크립트를 비롯한 대부분의 프로그래밍 언어는 렉시컬 스코프를 사용한다.

    // 1번의 경우 aaa함수가 부모함수 인것처럼 보이지만 bbb의 상위 스코프는 전역 스코프이므로 전역변수 1을 출력한다.
    // 2번의 경우 상위 스코프인 전역 변수 1을 출력한다.
    
    var a = 1;
    
    function aaa() {
        var a = 10;
        bbb();
    }
    
    function bbb() {
        console.log(a);
    }
    
    aaa(); // (1) 1
    bbb(); // (2) 1

'Javascript' 카테고리의 다른 글

[Javascript] 실행 컨텍스트  (0) 2021.07.20
[Javascript] this  (0) 2021.07.09
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03
[Javascript] 함수(function)  (0) 2021.06.30

- 자바스크립트의 모든 객체는 자신의 부모 역할을 담당하는 객체와 연결되어 있다

- 이것은 마치 객체 지향의 상속 개념과 같이 부모 객체의 프로퍼티 또는 메소드를 상속받아 사용할 수 있게 한다

- 부모 객체를 Prototype(프로토타입) 객체 또는 줄여서 Prototype(프로토타입)이라 한다.

'Javascript' 카테고리의 다른 글

[Javascript] this  (0) 2021.07.09
[Javascript] 스코프(Scope)  (0) 2021.07.08
[Javascript] 호이스팅  (0) 2021.07.03
[Javascript] 함수(function)  (0) 2021.06.30
[Javascript] 객체와 변경불가성(Immutability)  (0) 2021.06.22

호이스팅

- var 선언문, function 선언문 등 모든 선언문이 해당 Scope의 선두로 옮겨진 것처럼 동작하는 특성

- 변수 선언 단계초기화 단계할당 단계와 분리되어 진행되기 대문에 호이스팅이 발생한다.

변수 호이스팅

- var 키워드 변수 생성과정 -

1. 선언 단계 : 변수 객체에 var 키워드로 선언된 변수를 등록한다. 이 변수 객체는 스코프 참조 대상이 된다.
2. 초기화 단계 : 변수 객체에 등록된 var 키워드 변수를 메모리에 할당한다. var 키워드 변수값undefined로 초기화 된다.
3. 할당 단계 : 초기화 단계에서 undefined로 초기화된 값을 실제값으로 할당한다.

var 키워드 변수 호이스팅 예제

    // var 키워드로 선언된 변수는 선언 단계와 초기화 단계가 한번에 이루어진다.
    // 즉 (1)보다 먼저 scope에 변수가 등록되고 
    // 변수는 메모리 공간을 확보한 후 undefined로 초기화된다.
    
    // var a; // 호이스팅
    console.log(a); // (1) undefined
    var a = 10; // (2)
    console.log(a) // (3) 10

함수 호이스팅

- 함수 선언문 호이스팅 O

- 함수 표현식 호이스팅 X

    // testA : 함수 선언문
    // testB : 함수 표현식
    
    testA(2) // 2
    testB(4) // testB is not a function
    
    function testA(num) {
        console.log(num)
    }
    var testB = function (num) {
        console.log(num)
    }
    
    testB(4) // 4

'Javascript' 카테고리의 다른 글

[Javascript] 스코프(Scope)  (0) 2021.07.08
[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 함수(function)  (0) 2021.06.30
[Javascript] 객체와 변경불가성(Immutability)  (0) 2021.06.22
[Javascript] 객체  (0) 2021.06.21

함수 선언문

// 함수 선언문

    function sum(num) {
        console.log(num + num) // 4
        return num + num
    }
    
    sum(2)

함수 표현식

- 자바스크립트 함수의 특성(일급객체)을 이용해 변수에 할당할 수 있다.

- 변수에 할당할 수 있기 때문에 함수명을 생략할 수 있는데 이것을 익명 함수라고 한다.(보통 함수 표현식에서는 함수명을 생략함)

// 함수 표현식

    var sum = function (num) {
        console.log(num + num) // 4
        return num + num
    }
    
    sum(2)

(1) 변수에 함수를 할당하고 변수명으로 호출하는 것이 아닌 함수명을 사용해 호출하게 되면 에러가 발생한다.

  (함수 표현식에서 사용한 함수명은 외부 코드에서 접근 불가능하기 때문)

(2) 함수 표현식과 함수 선언문에서 사용한 함수명은 함수 내부에서 재귀적 호출, 디버거가 해당 함수를 구분할 수 있는 식별자 역할을 한다

//  1번 예시

    var sum = function add (num) {
        console.log(num + num) // 4
        return num + num
    }
    
    add(2) // add is not defined (변수명으로 호출하지 않고 함수명으로 호출하면 에러가 발생한다)
    // 2번 예시 
    
    var sum = function add (num) {
        console.log(num + num)
        if(num == 2) {
            console.log('재귀 호출')
            add(3) // 함수 내부에서는 함수명으로 재귀적 호출이 가능하다
        }

        return num + num
    }
    
    sum(2)

즉시 실행 함수

- 함수의 정의와 동시에 실행되는 함수를 즉시 실행 함수 라고 한다.

- 최초 한번만 호출 가능하고 다시 호출이 불가능하다.

    (function test(){
      console.log("hi") // hi
    }())
    
    test() // test is not defined

내부 함수

- 함수 내부에 정의된 함수를 내부함수(Inner function)라 한다.

- 내부함수는 자신을 포함하고 있는 부모함수 변수에 접근 가능하다

- 부모함수는 자식함수의 변수에 접근할 수 없다.

- 내부함수는 부모함수가 아닌 외부에서 접근이 불가능하다.

    function parent(str) {
        var position = '원딜';
        
        function child() {
            var line = "바텀";
            console.log(`${str}은 ${position}이고 ${line} 라인 입니다`);
        }
        
        child();
        console.log(`${str}의 라인은 ${line} 입니다.`); // line is not defined
                                                                   	   // 부모함수는 자식함수(내부함수)의 변수에 접근할 수 없다
    }
    
    parent('이즈리얼')
    child() // child is not defined
              // 내부함수는 부모함수 외부에서 접근할 수 없다.

콜백함수

- 특정 이벤트가 발생했을 때 시스템에 의해 호출되는 함수를 말한다.

- 보통 비동기식 처리 모델에서 사용된다.

    function callback(num) {
        for(var i=0; i<=num; i++) {
            if(i === num) {
                test() // 콜백함수 호출
            }
        }
        function test() { // 콜백함수
            console.log("콜백함수 실행")
        }
    }
    callback(5)

'Javascript' 카테고리의 다른 글

[Javascript] 프로토타입(Prototype)  (0) 2021.07.07
[Javascript] 호이스팅  (0) 2021.07.03
[Javascript] 객체와 변경불가성(Immutability)  (0) 2021.06.22
[Javascript] 객체  (0) 2021.06.21
[Javascript] 데이터 타입  (0) 2021.06.18

변경 불가능한 값(immutable value) vs 변경 가능한 값(mutable value)

- 원시 타입은 변경 불가능한 값이다.

- 객체 타입은 변경 가능한 값이다.

 

원시 타입

- 원시 타입은 값을 변경 할 수 없다. 하지만 재할당은 가능하다.(값이 변경되는것처럼 느껴지지만 변수가 가리키는 메모리 주소가 변경되는것이다.)

- string, number, bigint, boolean, undefined 등이 있다.

    var str = 'hello';
    str[0] = 's'; // Cannot assign to read only property '0' of string 'hello'
    str = 'world'; // O 재할당 가능

참조 타입

- 참조 타입은 값을 변경 할 수 있다.

    var me = {
        name : 'Kim',
        age : 25
    }
    
    var you = me;
    console.log(me.age) // 25
    you.age = 26
    console.log(me.age) // 26

1. me객체의 참조 주소가 you객체에 복사되었다.

2. you객체와 me 객체는 같은 주소를 참조하고 있다.

3. you객체의 age값을 변경하면 me age값 또한 바뀐다.(같은 주소를 참조하고 있기 때문에)

 

헷갈리는 예제

    var a = {
        name : 'lee'
    }
    var b = a.name;
    a.name = 'kim';
    
    console.log(typeof a); // object
    console.log(typeof b); // string
    console.log(a.name); // kim
    console.log(b) // lee

1. a객체는 객체 타입이지만 b에 값을 할당할 때

2. a객체의 참조 주소를 복사한게 아니라 a.name의 string값을 복사하여 넘겨주었다.

3. 즉 a객체의 프로퍼티 값을 변경 하더라도 b변수에는 영향이 없다.

 

불변 데이터 패턴

- 객체를 불변객체로 만들어 기존 객체의 프로퍼티 변경을 방지하는 패턴

1. Object.assign

// 문법
Object.assign(target, ...sources)

- 타겟 객체에 소스 객체의 프로퍼티를 복사한다.

- 기존 객체(소스 객체)를 변경하지 않고 객체를 복사 할 수 있다.

- 하지만 완전한 깊은복사(deep copy)를 지원하지 않는다(이유 : 객체 내부의 객체는 얕은복사(shallow copy)된다.)

    var me = { age : 25 };
    var assign = Object.assign({}, me);
    
    console.log(me); // { age: 25 }
    console.log(assign); // { age: 25 }
    console.log(me == assign); // false 프로퍼티 값만 복사하고 참조 주소는 다르기 때문에
    // 기존의 객체 프로퍼티는 변경되지 않고 프로퍼티 값을 복사하여 사용할 수 있다.
   
    var name1 = { a : 'Kim' };
    var name2 = { b : 'Lee' };
    var name3 = { c : 'Park'};
    
    var merge = Object.assign({}, name1, name2, name3);
    
    console.log(name1); // { a: 'Kim' }
    console.log(name2); // { b: 'Lee' }
    console.log(name3); // { c: 'Park' }
    console.log(merge); // { a: 'Kim', b: 'Lee', c: 'Park' }
    const me = {
        name : 'Kim',
        hobby : {
            game : 'LOL'
        }
    };
    const me1 = Object.assign({}, me);
    // me와 me1 객체는 참조 주소가 다르다. 
    console.log(me == me1) // false
    
    me1.name = 'Lee'
    console.log(me.name) // Kim
    console.log(me1.name) // Lee
    
    // 객체 내부의 객체는 얕은복사(shallow copy)가 되어서 둘중에 값이 변경되면 같이 값이 변한다.
    // const로 선언되어 있어도 객체 프로퍼티의 값은 변경이 가능하다.
    me.hobby.game = 'dota';
    console.log(me.hobby.game); // dota
    console.log(me1.hobby.game); // dota

 

'Javascript' 카테고리의 다른 글

[Javascript] 호이스팅  (0) 2021.07.03
[Javascript] 함수(function)  (0) 2021.06.30
[Javascript] 객체  (0) 2021.06.21
[Javascript] 데이터 타입  (0) 2021.06.18
자잘한 용어 정리  (0) 2021.06.09

+ Recent posts