πŸ“… TIL #17

객체, μŠ€μ½”ν”„μ™€ 클둜져


πŸ‘‰ 객체(Object)

1.extend (obj1, obj2)

두 개의 객체λ₯Ό μž…λ ₯λ°›μ•„ λ‘λ²ˆμ§Έ 객체의 속성듀을 첫번째 객체에 μΆ”κ°€ν•΄μ•Ό ν•œλ‹€.

  • μ£Όμ˜μ‚¬ν•­ :
  1. λ‘λ²ˆμ§Έ κ°μ²΄λŠ” μˆ˜μ •ν•˜μ§€ μ•Šμ•„μ•Ό 함.
  2. μΆ”κ°€ν•˜λ €λŠ” 속성이 이미 첫번째 객체에 μžˆλŠ” 경우, κΈ°μ‘΄κ°’ μœ μ§€
  • μž…μΆœλ ₯ μ˜ˆμ‹œ
const obj1 = {
    a: 1,
    b: 2
};

const obj2 = {
    b: 4,
    c: 3
};

extend(obj1, obj2);
console.log(obj1); // --> {a: 1, b: 2, c: 3}
console.log(obj2); // --> {b: 4, c: 3}
  • pseudocode(μˆ˜λ„μ½”λ“œ)
  1. for..in loop λ₯Ό μ΄μš©ν•΄μ„œ obj2 객체λ₯Ό μˆœνšŒν•œλ‹€.
  2. obj1 에 obj2의 keyκ°€ μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
  3. μ—†μœΌλ©΄ obj1에 obj2의 속성을 λ„£μ–΄μ€€λ‹€.


  • code
  for (let key in obj2) {
    if (!(key in obj1)) {      // μ΄λŸ°μ‹μœΌλ‘œ obj1에 obj2의 key값이 μžˆλŠ”μ§€ ν™•μΈν•œλ‹€.
      obj1[key] = obj2[key]    // μ—†λ‹€λ©΄ κ·Έ 속성을 obj1에 ν• λ‹Ήν•œλ‹€.
    }
  }
}



2.countAllCharacters (str)

각 ν‚€μ˜ 값은 ν•΄λ‹Ή λ¬Έμžκ°€ λ¬Έμžμ—΄μ—μ„œ λ“±μž₯ν•˜λŠ” 횟수λ₯Ό μ˜λ―Έν•˜λŠ” number νƒ€μž…μ˜ 값이어야 ν•œλ‹€.

  • μ£Όμ˜μ‚¬ν•­ :
  1. 빈 λ¬Έμžμ—΄μ„ μž…λ ₯받은 경우, 빈 객체λ₯Ό 리턴
  2. λ„μ–΄μ“°κΈ°λŠ” μ œμ™Έ
  • μž…μΆœλ ₯ μ˜ˆμ‹œ
let output = countAllCharacters("hello blog");
console.log(output); // --> {h: 1, e: 1, l: 3, o: 2, b: 1, g: 1}
  • pseudocode(μˆ˜λ„μ½”λ“œ)
  1. μš”μ†Œλ₯Ό λ‹΄μ•„ 쀄 μƒˆλ‘œμš΄ 빈 객체λ₯Ό ν• λ‹Ήν•œλ‹€.
  2. 반볡문으둜 λ¬Έμžμ—΄μ„ μˆœνšŒν•œλ‹€.
  3. 곡백을 λ§Œλ‚¬μ„ 경우 κ±΄λ„ˆλ›΄λ‹€.
  4. 순회λ₯Ό ν•˜λ©΄μ„œ 빈 객체의 key 값은 아직 undefined μ΄λ―€λ‘œ, 빈 객체의 μš”μ†Œκ°€ undefined 이면 0 으둜 할당을 ν•΄μ€€λ‹€.
  5. 그리고 반볡문이 순회 ν•  λ™μ•ˆ key 의 value값을 ++ ν•΄μ€€λ‹€.
  6. 빈 객체에 값이 λ“€μ–΄κ°„ 객체λ₯Ό 리턴해쀀닀.


  • code
let obj = {};

for (let i = 0; i < str.length; i++) {
    if (str[i] === " ") {
        continue;
    }
    if (obj[str[i]] === undefined) {
        obj[str[i]] = 0;
    }
    obj[str[i]]++;
}
return obj;

κ°μ²΄λŠ” ν™•μ‹€νžˆ μ΄λ‘ λ³΄λ‹€λŠ” 문제λ₯Ό ν’€λ©΄μ„œ 곡뢀λ₯Ό ν•΄μ•Ό 더 빨리 이해가 λ˜λŠ” 것 κ°™λ‹€!!

μ²˜μŒμ—λŠ” 객체에 value 값은 μ–΄λ–»κ²Œ 할당이 λ˜λŠ”κ±΄μ§€, key값은 뭐지? 이러고 많이 μ–΄λ €μ›Œ ν–ˆμ—ˆλŠ”λ°, λŠμž„μ—†μ΄ λ³΅μŠ΅ν•˜κ³  계속 문제λ₯Ό ν’€λ‹€λ³΄λ‹ˆ μ΄λŸ¬ν•œ λ¬Έμ œλ“€μ€ κ°€λ³κ²Œ ν’€κ²Œ λ˜μ—ˆλ‹€!



πŸ‘‰ Primitive vs Reference

1.Primitive type

Primitive type, μ›μ‹œ μžλ£Œν˜•μ˜ νƒ€μž…μ€ λ³€μˆ˜μ—λŠ” ν•˜λ‚˜μ˜ μ›μ‹œ μžλ£Œν˜•λ§Œμ„ 담을 수 μžˆλ‹€.

μ—¬κΈ°μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈμ—λŠ” number, string, boolean, undefined, null, symbol, bigint κ°€ μžˆλ‹€.

μ›μ‹œνƒ€μž…μ— μ†ν•˜λŠ” 값은 단 ν•˜λ‚˜μ˜ 데이터 κ°’λ§Œμ„ 가지고 μžˆλ‹€.

κ·Έλ ‡κΈ° λ•Œλ¬Έμ—, μ›μ‹œ μžλ£Œν˜•μ˜ μ €μž₯ κ³΅κ°„μ˜ ν¬κΈ°λŠ” 고정이라고 보면 λœλ‹€. 그리고 이 μ €μž₯ 곡간은 β€œCall Stack” 이라고 λΆ€λ₯Έλ‹€.

let word = "hello blog!";
word = "welcome to my blog!";
// μ›μ‹œνƒ€μž…μΈ string은 λ³€κ²½ν•  수 μ—†λŠ” κ³ μ •λœ κ°’μ΄μ§€λ§Œ,
// μ΄λŸ°μ‹μœΌλ‘œ μž¬ν• λ‹Ήμ„ ν•˜μ—¬ λ³€μˆ˜ "word"에 λ‹΄κΈ΄ λ‚΄μš©μ„ λ³€κ²½ν•  수 λŠ” μžˆλ‹€.


  • μ›μ‹œ μžλ£Œν˜•μ˜ μ˜ˆμ‹œ
let str1 = "hello";
let str2 = str1;
str2 = "world";

console.log(str1); // "hello"



2.Reference type

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μ›μ‹œ μžλ£Œν˜•μ΄ μ•„λ‹Œ λͺ¨λ“  것은 μ°Έμ‘° μžλ£Œν˜•(Reference type) 이라고 보면 λœλ‹€.

λŒ€ν‘œμ μΈ 것은 λ°°μ—΄([])κ³Ό 객체({}), ν•¨μˆ˜(function(){})이 μžˆλ‹€.

μ°Έμ‘° μžλ£Œν˜•μ€ μ›μ‹œ μžλ£Œν˜•κ³ΌλŠ” 달리 μ €μž₯ κ³΅κ°„μ˜ μ£Όμ†Œκ°’μ„ ν• λ‹Ήν•œλ‹€. κ·Έλž˜μ„œ 이 μ €μž₯ 곡간은 κ³ μ •λœ 크기가 μ•„λ‹ˆλΌ, λ™μ μœΌλ‘œ 크기가 λ³€ν•˜λŠ” νŠΉλ³„ν•œ μ €μž₯ 곡간을 μ‚¬μš©ν•œλ‹€. μš°λ¦¬λŠ” 이 μ €μž₯ 곡간을 β€œheap” 이라고 λΆ€λ₯Έλ‹€.

  • μ°Έμ‘° μžλ£Œν˜•μ˜ μ˜ˆμ‹œ
let x = { foo: 1 };
let y = x;
y.foo = 2;

console.log(x.foo); // 2

x 에 {foo: 1} λ₯Ό ν• λ‹Ήν–ˆκ³ , yμ—λŠ” x의 μ£Όμ†Œκ°’μ„ ν• λ‹Ήν–ˆλ‹€. x와 yλŠ” 같은 μ£Όμ†Œλ₯Ό 바라보고 있으며, y.fooκ°€ 2둜 λ³€κ²½λ˜μ—ˆμœΌλ‹ˆ, 같은 곳을 λ°”λΌλ³΄λ˜ x.foo도 2둜 λ°”λ€Œκ²Œ λœλ‹€.



πŸ‘‰ Scope


μŠ€μ½”ν”„λŠ” λ³€μˆ˜ μ ‘κ·Ό κ·œμΉ™μ— λ”°λ₯Έ 유효 λ²”μœ„

λ³€μˆ˜μ™€ κ·Έ 값이, μ–΄λ””μ„œλΆ€ν„° μ–΄λ””κΉŒμ§€ μœ νš¨ν•œμ§€λ₯Ό νŒλ‹¨ν•˜λŠ” λ²”μœ„

JavaScriptλŠ” 기본적으둜, ν•¨μˆ˜κ°€ μ„ μ–Έλ˜λŠ”(lexical) λ™μ‹œμ— μžμ‹ λ§Œμ˜ Scopeλ₯Ό 가진닀.


let git = "Hello"; // μ „μ—­ λ³€μˆ˜

function welcomeToMyBlog() {
    let myName = "Useong"; // 지역 λ³€μˆ˜

    return git + " " + myName;
}

console.log(welcomeToMyBlog()); // 'Hello Useong'
console.log(myName); // ReferenceError

μ—¬κΈ°μ„œ git 은 μ „μ—­ λ³€μˆ˜μ— ν•΄λ‹Ήν•˜κ³ , myName 은 지역 λ³€μˆ˜μ— ν•΄λ‹Ήν•œλ‹€.

ScopeλŠ” 쀑첩이 κ°€λŠ₯ν•˜λ‹€. μ „μ—­ λ³€μˆ˜λŠ” μ–΄λ””μ„œλ“  접근이 κ°€λŠ₯ν•˜λ‹€.

지역 λ³€μˆ˜λŠ” ν•¨μˆ˜ λ‚΄μ—μ„œ μ „μ—­ λ³€μˆ˜λ³΄λ‹€ 더 높은 μš°μ„ μˆœμœ„λ₯Ό 가진닀.

1.μŠ€μ½”ν”„ 문제

let x = 10;

function outer() {
    x = 20;

    function inner() {
        let x;
        x = x + 20;

        return x;
    }
    inner();
}

outer();
let result = x;

console.log(outer()); // undefined
console.log(result); // 20


1.result λŠ” μ™œ 20 일까 ?

outer ν•¨μˆ˜μ—μ„œ μ „μ—­ λ³€μˆ˜ x 에 20을 μž¬ν• λ‹Ήν–ˆκΈ° λ•Œλ¬Έμ΄λ‹€. κ·Έλž˜μ„œ result 의 값은 20 이닀. outer λ‚΄λΆ€μ—μ„œ inner ν•¨μˆ˜κ°€ 호좜 되고 μžˆμ§€λ§Œ, inner ν•¨μˆ˜λŠ” λ°”κΉ₯ μŠ€μ½”ν”„μ— μ•„λ¬΄λŸ° 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠλŠ”λ‹€.

2.그러면 μ™œ μ•„λ¬΄λŸ° 영ν–₯을 λ―ΈμΉ˜μ§€ μ•Šμ„κΉŒ ?

inner ν•¨μˆ˜μ—λŠ” x λΌλŠ” 지역 λ³€μˆ˜, μƒˆλ‘œμš΄ λ³€μˆ˜κ°€ ν• λ‹Ήλ˜μ–΄ μžˆλ‹€. κ·Έλ ‡κΈ° λ•Œλ¬Έμ—, inner ν•¨μˆ˜ μ•ˆμ— μžˆλŠ” xλŠ” λ°”κΉ₯ μŠ€μ½”ν”„μ—λŠ” 영ν–₯을 λ―ΈμΉ  수 κ°€ μ—†λ‹€.

그리고 let x; λŠ” 선언은 λ˜μ–΄μžˆμ§€λ§Œ, 할당이 λ˜μ–΄μžˆμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— x 의 값은 undefined 이닀. 그리고 x = x + 20은 undefined 에 숫자 20을 λ”ν–ˆκΈ° λ•Œλ¬Έμ— NaN μ΄λΌλŠ” 결과값이 λ‚˜μ˜¨λ‹€.

inner ν•¨μˆ˜λŠ” NaN 을 λ°˜ν™˜ν•˜κ²Œ 되고 inner ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” outer ν•¨μˆ˜λŠ” undefinedκ°€ λœλ‹€. κ·Έλž˜μ„œ κ²°κ΅­, outer() 의 결과값은 undefined 인 μ…ˆμ΄λ‹€.



πŸ‘‰ Closure

ν΄λ‘œμ €λŠ” μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό λœ»ν•œλ‹€. μ™ΈλΆ€ν•¨μˆ˜μ˜ 싀행이 μ’…λ£Œλœ 후에도, ν΄λ‘œμ €λŠ” μ™ΈλΆ€ν•¨μˆ˜μ˜ μŠ€μ½”ν”„λ₯Ό μ°Έμ‘°ν•  수 μžˆλ‹€.

ν΄λ‘œμ €μ˜ 단점 : 일반 ν•¨μˆ˜μ˜€λ‹€λ©΄ ν•¨μˆ˜ μ‹€ν–‰ μ’…λ£Œ ν›„ 가비지 μ»¬λ ‰μ…˜(μ°Έκ³  자료: MDN β€˜μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ©”λͺ¨λ¦¬ 관리’) λŒ€μƒμ΄ λ˜μ—ˆμ„ 객체가, ν΄λ‘œμ € νŒ¨ν„΄μ—μ„œλŠ” λ©”λͺ¨λ¦¬ 상에 남아 있게 λœλ‹€.

μ™ΈλΆ€ ν•¨μˆ˜ μŠ€μ½”ν”„κ°€ λ‚΄λΆ€ ν•¨μˆ˜μ— μ˜ν•΄ μ–Έμ œλ“ μ§€ 참쑰될 수 있기 λ•Œλ¬Έμ΄λ‹€. λ”°λΌμ„œ ν΄λ‘œμ €λ₯Ό λ‚¨λ°œν•  경우 νΌν¬λ¨ΌμŠ€κ°€ μ €ν•˜λ  수 도 μžˆλ‹€.


:point_up: 가비지 μ»¬λ ‰μ…˜μ΄λž€, μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 객체가 μƒμ„±λ˜μ—ˆμ„ λ•Œ μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜κ³  μ“Έλͺ¨ μ—†μ–΄μ‘Œμ„ λ•Œ μžλ™μœΌλ‘œ ν•΄μ œν•˜λŠ” 것이닀. 값을 μ„ μ–Έν•  λ•Œ μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•œλ‹€κ³  보면 λœλ‹€.

κ·Έλž˜μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 가비지 μ»¬λ ‰μ…˜μ„ 톡해 λ©”λͺ¨λ¦¬λ₯Ό κ΄€λ¦¬ν•œλ‹€. 객체가 μ°Έμ‘° λŒ€μƒμ΄ 아닐 λ•Œ, 가비지 μ»¬λ ‰μ…˜μ— μ˜ν•΄ μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬ 할당이 ν•΄μ œλœλ‹€.


1.컀링 (currying)

컀링 (currying) : ν•¨μˆ˜ ν•˜λ‚˜κ°€ n 개의 인자λ₯Ό λ°›λŠ” λŒ€μ‹ , n개의 ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄ 각각 인자λ₯Ό λ°›κ²Œ ν•˜λŠ” 방법

function adder(x) {
    return function (y) {
        return x + y;
    };
}

adder(2)(3); // 5


function htmlMaker(tag) {
    let startTag = `<${tag}>`;
    let endTag = `</${tag}>`;

    return function (textContent) {
        return startTag + textContent + endTag;
    };
}
let divMaker = htmlMaker("div");

divMaker("μ•ˆλ…•ν•˜μ„Έμš”");
// "<div>μ•ˆλ…•ν•˜μ„Έμš”</div>"

let spanMaker = htmlMaker("span");

spanMaker("λΈ”λ‘œκ·Έμ— μ˜€μ‹  κ±Έ ν™˜μ˜ν•©λ‹ˆλ‹€.");
// "<span>λΈ”λ‘œκ·Έμ— μ˜€μ‹  κ±Έ ν™˜μ˜ν•©λ‹ˆλ‹€.</span>"



2.ν΄λ‘œμ € λͺ¨λ“ˆ νŒ¨ν„΄

ν΄λ‘œμ € λͺ¨λ“ˆ νŒ¨ν„΄ : λ³€μˆ˜λ₯Ό μŠ€μ½”ν”„ μ•ˆμͺ½μ— 가두어 ν•¨μˆ˜ λ°–μœΌλ‘œ λ…ΈμΆœ μ‹œν‚€μ§€ μ•ŠλŠ” 방법

function makeCounter() {
    let privateCounter = 0;

    return {
        increment: function () {
            privateCounter++;
        },
        decrement: function () {
            privateCounter--;
        },
        getValue: function () {
            return privateCounter;
        }
    };
}

let counter1 = makeCounter();

counter1.increment();
counter1.increment();

console.log(counter1.getValue()); // 2


3.ν΄λ‘œμ € 문제

ν΄λ‘œμ € ν•¨μˆ˜μ˜ 문제λ₯Ό ν’€μ–΄λ³΄λ©΄μ„œ 이해λ₯Ό ν•΄λ³΄μž! total의 값은 λ¬΄μ—‡μΌκΉŒ?

let add = fucntion(x) {
    let sum = function(y) {
      return x + y;
    }
    return sum;
}

let foo = add(1);
foo(3);
let total = foo(6);


console.log(total) // ?


total = 7

total 은 μ™œ 7값이 λ‚˜μ˜¬κΉŒ ?

ν•¨μˆ˜ add λŠ” xλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ ν•˜λ©°, sum을 λ°˜ν™˜ν•œλ‹€. μ—¬κΈ°μ„œ 전달받은 x λŠ” λ‚΄λΆ€ν•¨μˆ˜ sum에 전달을 ν•΄μ€€λ‹€. μ΄λ•Œ, sum 은 x + y λ₯Ό λ°˜ν™˜ν•˜λ©΄μ„œ μ™ΈλΆ€ν•¨μˆ˜μΈ add의 λ§€κ°œλ³€μˆ˜ x 에 μ ‘κ·Όν•  수 μžˆλ‹€. (ν΄λ‘œμ € ν•¨μˆ˜μ˜ κ°œλ…)

κ·Έλ ‡λ‹€λ©΄ fooλŠ” add(1) 을 ν• λ‹Ήν•˜κ³ , total은 foo(6)을 ν• λ‹Ήν–ˆκΈ° λ•Œλ¬Έμ—, let total = foo(1)(6) κ³Ό 같은 뜻이 λœλ‹€.

λ”°λΌμ„œ, return x + y => 1 + 6 이 되고 7을 λ°˜ν™˜ν•˜κ²Œ λœλ‹€.

foo(3) 은 무슨 역할을 ν• κΉŒ?

foo(3) 을 μ‹€ν–‰ν•˜κ²Œ 되면 foo(1)(3) 이 λ˜μ–΄ 4λΌλŠ” 값이 λ°˜ν™˜λ  수 도 μžˆμ§€λ§Œ, ν˜„μž¬ foo(3)은 어디에도 할당이 λ˜μ–΄ μžˆμ§€ μ•ŠμœΌλ―€λ‘œ total μ—λŠ” μ•„λ¬΄λŸ° 영ν–₯을 λ―ΈμΉ˜μ§€ μ•ŠλŠ”λ‹€.



πŸ‘Š λ‚΄μΌμ˜ TIW(today I Will)

git