Core Javascript #1

Daeung Kim·2023년 12월 18일
0

corejavascript

목록 보기
1/2

01 데이터 타입


01 데이터 타입의 종류

JavaScript Data Types

Primitive Type (기본형) : 할당 / 연산 시 복제, immutability

  • number
  • string
  • boolean
  • null
  • undefined
  • Symbol

Reference Type (참조형) - object : 할당 / 연산 시 참조

  • Map, WeakMap
  • Set, WeakSet
  • Array
  • Function
  • Date
  • RegExp

엄밀히 말하면 Primitive와 Reference 모두 복제를 하긴 한다.

다만 기본형은 값이 담긴 주솟값을 바로 복제하는 반면 참조형은 값이 담긴 주솟값들로 이루어진 묶음의 주솟값을 복제한다는 점이 다르다.


02 데이터 타입에 관한 배경지식

메모리와 데이터

Understanding the Relationship between Bits and Bytes

  • bit : 0, 1 을 표현하는 하나의 메모리 조각, unique identifier(고유 식별자)를 통해 위치를 확인할 수 있다.
  • byte: 비트 단위로 위치를 확인하는 것의 비효율을 해결하기 위해 생긴 단위, 8개의 비트의 묶음으로 구성되어 있다. 모든 데이터는 memory address(메모리 주솟값, 8바이트 단위의 식별자)로 위치 확인

식별자와 변수

  • variable(변수): 변할 수 있는 데이터
  • identifier(식별자): 어떤 데이터를 식별하는 데 사용하는 이름, 변수명

03 변수 선언과 데이터 할당

변수 선언

var a

: 식별자가 a인 변할 수 있는 데이터를 만든다.

var a
a = "abc"


var a = "abc"

같은 동작 수행

문자열 변환에 대한 메모리 영역의 변화

코어 자바스크립트  데이터 타입

: 변수 재할당시 기존 "abc"가 저장된 주소에 "abcdef"를 할당하는 대신 별도의 공간에 새로 만든 뒤에 그 주소를 a 변수에 연결한다.


04 기본형 데이터와 참조형 데이터

불변값: 변경 가능성을 기준으로 variable(변수)/constant(상수)

var a = "abc"
a = a + "def"
// 새로운 "abcdef"라는 데이터를 만들어 a에 재할당

var b = 5
var c = 5
b = 7
// 새로운 7이라는 데이터를 만들어 b에 재할당
  • 변경 가능성의 대상은 변수 영역 이며 한 번 데이터 할당이 이뤄진 변수 공간에 다른 데이터를 재할당할 수 있는지 여부가 관건이다.
  • 불변성 여부를 구분할 때의 변경 가능성의 대상은 데이터 영역 메모리이다.

기본형 데이터는 모두 불변값으로, 한 번 만든 값을 바꿀 수 없고, 변경은 새로 만드는 동작을 통해서만 이루어진다.

가변값

참조형 데이터의 할당
var obj1 = {
    a: 1,
    b: "bbb"
}

Core Javascript 1

  • 객체의 변수(프로퍼티) 영역이 별도로 존재한다 > 데이터 영역에 저장된 값은 불변하지만, 변수에는 얼마든지 다른 값을 대입할 수 있기에 참조형 데이터는 가변하다고 얘기한다.
  • 자신의 주소를 참조하는 변수가 하나도 없는 경우 즉, 참조 카운트가 0인 메모리 주소는 GC(garbage collector)의 수거대상이 되어 다시 새로운 값을 할당할 수 있는 빈 공간이 된다.

변수 복사 비교

var a = 10
var b = a

var obj1 = {
    c: 10,
    d: "ddd"
}
var obj2 = obj1


b = 15
obj2.c = 20

🐯 코어 자바스크립트  01 데이터 타입

  • 기본형 데이터는 각 값을 데이터 영역에 저장하고 그 주소를 변수의 값으로 지정하는 반면, 참조형 데이터는 해당 필요한 데이터들이 저장된 주솟값의 묶음의 주소를 변수의 값으로 지정한다.
  • 이후 b와 obj2.c의 값을 변경할 때, 결과적으로 a !==b, obj1 === obj2인 형태가 된다.(변수의 값에 저장된 내용을 기준으로 판단하기 때문)

05 불변 객체

immutable object(불변 객체)를 만드는 간단한 방법

객체의 가변성에 따른 문제점

var user = {
    name: "Jaenam",
    gender: "male"
}

var changeName = function(user, newName) {
    var newUser = user
    newUser.name = newName
    return newUser
}

var user2 = changeName(user, "Jung")


// console.log(user.name, user2.name) // Jung Jung
// console.log(user === user2) // true

객체의 가변성에 따른 문제점 해결 방법

: changeName 함수의 return으로 새로운 객체를 반환

var user = {
    name: "Jaenam",
    gender: "male"
}

var changeName = function(user, userName) {
    return {
        name: newName,
        gender: user.gender
    }
}

var user2 = changeName(user, "Jung")

// console.log(user.name, user2.name) // Jaenam Jung
// console.log(user === user2) // false

user의 gender를 하드코딩하는 문제점에 대한 해결 방법

: shallow copy(얕은 복사)를 통해 기존 정보를 복사해서 새로운 객체를 반환

var copyObject = function(target) {
    var result = {}
    for (var prop in target) {
        result[prop] = target[prop]
    }

    return result
}

얕은 복사와 깊은 복사

중첩된 객체에 대한 얕읕 복사

var user = {
    name: "Jaenam",
    urls: {
        portfolio: "http://github.com/abc",
        blog: "http://blog.com",
        facebook: "http://facebook.com/abc"
    }
}


var user2 = copyObject(user)


user2.name = "Jung"
console.log(user.name === user2.name) // false


user.urls.portfolio = "http://portfolio.com"
console.log(user.urls.portfolio === user2.urls.portfolio) // true

: shallow copy(얕은 복사)는 바로 아래 단계의 값만 복사하기 때문에 user.urls.portfolio는 모두 동일한 참조형 데이터의 주소를 가리키게 된다. 즉 user, user2 모두 "http://portfolio.com" 으로 값이 변경

중첩된 객체에 대한 깊은 복사

var user2 = copyObject(user)
user2.urls = copyObject(user.urls)

user.urls.portfolio = "http://portfolio.com"
console.log(user.urls.portfolio === user2.urls.portfolio) // false

user2.urls.blog = ""
console.log(user.urls.blog === user2.urls.blog)

: shallow copy와 달리 참조형 데이터에 대해서 deep copy(깊은 복사)를 진행 해 가리키는 주솟값이 위의 코드와 비교했을 때 다름을 알 수 있다.

객체의 깊은 복사를 수행하는 범용 함수

var copyObjectDeep = function(target) {
    var result = {}
    if (typeof target === "object" && target !== null) {
        for (var prop in target) {
            result[prop] = copyObjectDeep(target[prop])
        }
    } else {
        result = target
    }
    return result
}

JSON을 활용한 간단한 깊은 복사

var copyObjectViaJSON = function(target) {
    return JSON.parse(JSON.stringify(target))
}

var obj = {
    a: 1,
    b: {
        c: null,
        d: [1, 2],
        func1: function() {console.log(3)}
        func2: function() {console.log(4)}
    }
}

var obj2 = copyObjectViaJSON(obj)

obj2.a = 3
obj2.b.c = 4
obj2.b.d[1] = 3

console.log(obj)
// {a: 1, b: {c: null, d: [1, 3], func1: f()}, func2: f()}
console.log(obj2)
// {a: 3, b: {c: 4, d: [1, 2]}}

06 undefined와 null

undefined를 반환하는 경우

  • 값을 대입하지 않은 변수, 즉 데이터 영역의 메모리 주소를 지정하지 않은 식별자에 접근할 때
  • 객체 내부의 존재하지 않는 프로퍼티에 접근하려고 할 때
  • return 문이 없거나 호출되지 않는 함수의 실행 결과

자동으로 undefined를 부여하는 경우

var a
console.log(a) // undefined

var obj = {a: 1}
console.log(obj.a) // 1
console.log(obj.b) // undefined
console.log(b) // c.f) ReferenceError: b is not defined

var func = function() {}
var c = func() // undefined
console.log(c) // undefined

undefined와 배열

var arr1 = []
arr1.length = 3
console.log(arr1) // [empty * 3]

var arr2 = new Array(3)
console.log(arr2) // [empty * 3]

var arr3 = [undefined, undefined, undefined]
console.log(arr3) // [undefined, undefined, undefined]

빈 요소와 배열의 순회

var arr1 = [undefined, 1]
var arr2 = []
arr2[1] = 1

arr1.forEach(function(v, i) { console.log(v, i) })
// undefined 0 / 1 1
arr2.forEach(function(v, i) { console.log(v, i) })
// 1 1

arr1.map(function(v, i) {return v + i })
// [NaN, 2]
arr2.map(function(v, i) {return v + i })
// [empty, 2]

arr1.filter(function(v) {return !v})
// [undefined]
arr2.filter(function(v) {retrun !v})
// []

arr1.reduce(function(p, c, i) {return p + c + i}, "")
// undefined011
arr2.reduce(function(p, c, i) {return p + c + i}, "")
// 11
  • "var a"라는 구문은 undefined를 할당하는 것이 아니다. 정확히는 아무것도 할당하지 않으며, 이후 a에 접근 하려 할 때 undefined를 반환할 뿐이다.
  • 위 예시에서 확인할 수 있듯, undefined를 직접 할당하는 경우 다양한 혼란을 야기할 가능성이 있다. 따라서 비어있음을 명시적으로 나타내고 싶을때는 대신 null을 사용하는 것이 일반적이다.
  • typeof null 은 object를 반환하는데 이는 자바스크립트 자체 버그이다.

null과 undefined의 비교

var a = null
console.log(typeof n) // object

console.log(n == undefined) // true
console.log(n == null) // trure

console.log(n === undefined) // false
console.log(n === null) // true

: equality operator(==, 동등연산자)로 비교할 경우 null과 undefined를 같다고 판단하나, identity operator(===, 일치연산자)로 비교할 경우 다르다고 판단한다.

0개의 댓글