본문으둜 κ±΄λ„ˆλ›°κΈ°

λ³€μˆ˜μ™€ μŠ€μ½”ν”„ λ©”λͺ¨λ¦¬

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λŠμŠ¨ν•œ νƒ€μž…(loosly typed) μ–Έμ–΄ ν˜Ήμ€ 동적(dynamic) μ–Έμ–΄λ‘œ, λ³€μˆ˜κ°€ κ°€μ Έμ•Ό ν•  데이터 νƒ€μž…μ„ 미리 μ„ μ–Έν•  ν•„μš”κ°€ μ—†κ³ , λ³€μˆ˜μ˜ νƒ€μž…μ΄ μ‹€ν–‰ 쀑에 λ°”λ€” 수 μžˆλŠ” 언어이닀.

var foo = 42; // Numbervar foo = 'bar'; // Stringvar foo = true; // Boolean

μ›μ‹œ κ°’κ³Ό μ°Έμ‘° κ°’#

μžλ°”μŠ€ν¬λ¦½νŠΈμ—λŠ” κΈ°λ³Έ νƒ€μž…(Primitive, λ˜λŠ” μ›μ‹œ μžλ£Œν˜•)κ³Ό μ°Έμ‘° νƒ€μž…(Reference)μ˜λ°μ΄ν„°λ₯Ό μ €μž₯ν•  수 μžˆλ‹€.

  • μ›μ‹œ νƒ€μž… : Number, String, Boolean, Undefined, Null, Symbol

    • 'κ°’μœΌλ‘œ' μ ‘κ·Ό

    • λ³€μˆ˜μ— μ €μž₯된 μ‹€μ œ 값을 μ‘°μž‘

  • μ°Έμ‘° νƒ€μž… : Object

    • '참쑰둜' μ ‘κ·Ό

    • 객체 μžμ²΄κ°€ μ•„λ‹ˆλΌ ν•΄λ‹Ή 객체에 λŒ€ν•œ 'μ°Έμ‘°'λ₯Ό μ‘°μž‘


☝️ μ›μ‹œ κ°’ vs μ°Έμ‘° κ°’μ˜ 차이λ₯Ό 머리 속에 λ°•μ•„λ‘μž.

Explaining Value vs. Reference in Javascript

μ›μ‹œ κ°’#

var x = 10;var y = 'abc';var z = null;
VariablesValues
x10
y'abc'
znull

μ°Έμ‘° κ°’#

var arr = [];arr.push(1);
VariablesValuesAddressesObjects
arr<#001>#001[]
VariablesValuesAddressesObjects
arr<#001>#001[1]

동적 ν”„λ‘œνΌν‹°#

μ°Έμ‘° κ°’μ—λŠ” μ–Έμ œλ“  ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œμ˜ μΆ”κ°€, μˆ˜μ •, μ‚­μ œκ°€ κ°€λŠ₯ν•˜λ‹€.

var person = new Object();person.name = 'Nicholas';alert(person.name); // "Nicholas"

μ›μ‹œ κ°’μ—λŠ” ν”„λ‘œνΌν‹°λ₯Ό μΆ”κ°€ν•  수 μ—†λ‹€. (μ—λŸ¬κ°€ λ°œμƒν•˜λŠ” 것은 μ•„λ‹ˆλ‹€.)

var name = 'Nicholas';name.age = 27;alert(name.age); // undefined

κ°’ 볡사#

μ›μ‹œ 값을 λ‹€λ₯Έ λ³€μˆ˜λ‘œ 볡사할 λ•ŒλŠ” ν˜„μž¬ μ €μž₯된 값을 μƒˆλ‘œ μƒμ„±ν•œ λ‹€μŒ μƒˆλ‘œμš΄ λ³€μˆ˜μ— λ³΅μ‚¬ν•œλ‹€. 두 λ³€μˆ˜λŠ” μ™„μ „νžˆ λΆ„λ¦¬λ˜μ–΄ μžˆλ‹€.

var num1 = 5;var num2 = num1;
  ![2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-0](./images/2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-0.png)


  ![2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-1](./images/2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-1.png)

μ°Έμ‘° κ°’ 볡사 μ—­μ‹œ μ›λž˜ λ³€μˆ˜μ— λ“€μ–΄ 있던 값이 λ‹€λ₯Έ λ³€μˆ˜λ‘œ λ³΅μ‚¬λ˜κΈ°λŠ” λ§ˆμ°¬κ°€μ§€μΈλ° , 이 λ•Œ λ³΅μ‚¬λ˜λŠ” 값은 객체 μžμ²΄κ°€ μ•„λ‹ˆλΌ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” ν¬μΈν„°λΌλŠ” 것이닀.

var obj1 = new Object();var obj2 = obj1;obj1.name = 'Nicholas';alert(obj2.name); // "Nicholas"

2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-2

두 λ³€μˆ˜κ°€ 같은 객체λ₯Ό 가리킀기 λ•Œλ¬Έμ— 객체의 ν”„λ‘œνΌν‹°λ₯Ό λ³€κ²½ν•˜λ©΄, 두 값이 λͺ¨λ‘λ³€κ²½λœλ‹€.

☝️ 였λ₯Έμͺ½μ— μžˆλŠ” λ©”λͺ¨λ¦¬ μ˜μ—­μ„ νž™(Heap)이라고 ν•œλ‹€.

λ§€κ°œλ³€μˆ˜ 전달#

ECMAScript의 ν•¨μˆ˜ λ§€κ°œλ³€μˆ˜λŠ” λͺ¨λ‘ κ°’μœΌλ‘œ 전달(Pass by value)λœλ‹€. 외뢀에 μžˆλŠ” 값을 ν•¨μˆ˜μ— 인자둜 λ„£μ–΄μ£Όλ©΄ λ§€κ°œλ³€μˆ˜μ— λ³΅μ‚¬λ˜μ–΄ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-3

☝️ λ§€κ°œλ³€μˆ˜(parameters)와 μ „λ‹¬μΈμž(arguments)

이 λ•Œ λ³΅μ‚¬λ˜λŠ” 방식은 μœ„μ—μ„œ μ„€λͺ…ν•œ κ°’ 볡사와 λ™μΌν•˜λ‹€. μ›μ‹œ 값은 ν˜Όλž€μ˜ μ—¬μ§€κ°€μ—†μ§€λ§Œ μ°Έμ‘° κ°’μ˜ 경우 ν˜Όλž€μ˜ 여지가 μžˆλ‹€.

function setName(obj) {    obj.name = 'Nicholas';}
var person = new Object();person.name = 'Alberto';setName(person);alert(person.name); // "Nicholas"

이 μ˜ˆμ œμ—μ„œ setName() ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜κ³  λ‚˜μ„œ person.name 이 바뀐 것을 보고 λ§€κ°œλ³€μˆ˜κ°€ μ°Έμ‘° ν˜•νƒœλ‘œ μ „λ‹¬λ˜μ—ˆλ‹€κ³  μ˜€ν•΄ν•˜λŠ” κ²½μš°κ°€ μžˆλ‹€. ν•˜μ§€λ§Œ, μ΄λŠ” ν•¨μˆ˜ λ‚΄μ—μ„œ μ°Έμ‘°λ₯Ό 톡해 λ©”λͺ¨λ¦¬μ— μžˆλŠ” 객체에 μ ‘κ·Όν•˜μ˜€κΈ° λ•Œλ¬Έμ— 객체의 ν”„λ‘œνΌν‹°λ₯Ό λ³€κ²½ν• μˆ˜ μžˆμ—ˆλ˜ 것이닀.

VariablesValues#AddressesObjects
person<#234>##234{name: "Alberto"} β†’ {name: "Nicholas"}
obj<#234>#
function setName(obj) {    obj = {        name: 'Nicholas',    };}
var person = new Object();person.name = 'Alberto';setName(person);alert(person.name); // "Alberto"

반면, ν•¨μˆ˜ λ‚΄λΆ€λ₯Ό λ§€κ°œλ³€μˆ˜ obj 에 μƒˆλ‘œμš΄ 객체λ₯Ό ν• λ‹Ήν•˜λŠ” κ²ƒμœΌλ‘œ λ³€κ²½ν•˜λ©΄ setName() ν•¨μˆ˜λ₯Ό 싀행해도 person.name 이 λ³€ν•˜μ§€ μ•Šμ€ 것을 λ³Ό 수 μžˆλ‹€.

μ²˜μŒμ—λŠ” λ§€κ°œλ³€μˆ˜ obj 에 person 의 μ£Όμ†Œ 값이 λ³΅μ‚¬λ˜μ—ˆμœΌλ‚˜, 이후에 obj μ—μƒˆλ‘œμš΄ 객체( {name: "Nicholas"} )λ₯Ό ν• λ‹Ήν•œ κ²ƒμœΌλ‘œ, 기쑴의 κ°μ²΄λŠ” 영ν–₯을 λ°›μ§€μ•ŠλŠ”λ‹€.

VariablesValues#AddressesObjects
person<#234>##234{name: "Alberto"}
obj<#234> β†’ <#567>##567{name: "Nicholas"}

Understanding JavaScript Pass By Value

νƒ€μž… νŒλ³„#

typeof μ—°μ‚°μžλŠ” λ³€μˆ˜κ°€ Number, String, Boolean, undefined 일 λ•ŒλŠ” μ •ν™•ν•œ νƒ€μž…μ„ μ•Œ 수 있고, κ°μ²΄μ΄κ±°λ‚˜ null 일 경우 objectλ₯Ό λ°˜ν™˜ν•œλ‹€.

객체가 μ–΄λ–€ νƒ€μž…μ˜ 객체인지 μ•Œκ³  싢을 λ•Œκ°€ μžˆλŠ”λ° 이 λ•ŒλŠ” typeof μ—°μ‚°μž λŒ€μ‹  instanceof μ—°μ‚°μžκ°€ 도움이 λœλ‹€. instanceof μ—°μ‚°μžλŠ” object의 ν”„λ‘œν† νƒ€μž… 체인에 constructor.prototype 이 μ‘΄μž¬ν•˜λŠ”μ§€ νŒλ³„ν•œλ‹€.

var person = {    name: 'Alberto',};var colors = ['red', 'blue', 'green'];
var fruit1 = new String('banana');var fruit2 = 'apple';
console.log(person instanceof Object); // trueconsole.log(colors instanceof Object); // trueconsole.log(colors instanceof Array); // trueconsole.log(fruit1 instanceof Object); // trueconsole.log(fruit1 instanceof String); // trueconsole.log(fruit2 instanceof Object); // falseconsole.log(fruit2 instanceof String); // false

μœ„μ™€ 같이 객체에 instanceof 을 μ΄μš©ν•΄ μ–΄λŠ 객체의 μΈμŠ€ν„΄μŠ€μΈμ§€λ₯Ό νŒλ³„ν•  수 μžˆλ‹€.

☝️ fruit1 κ³Ό fruit2 의 차이에 μœ μ˜ν•˜μž. fruit1 은 String 객체λ₯Ό μƒμ„±ν•œκ²ƒμ΄κ³ , fruit2 λŠ” λ¦¬ν„°λŸ΄λ‘œ κΈ°λ³Έ νƒ€μž… String 값이닀.

[μžλ°”μŠ€ν¬λ¦½νŠΈ] new String("")κ³Ό ""(String literal)κ³Ό String("")에 λŒ€ν•˜μ—¬

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ μŠ€μ½”ν”„#

λ³€μˆ˜λ‚˜ ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λ‹€λ₯Έ 데이터에 μ ‘κ·Όν•  수 μžˆλŠ”μ§€, μ–΄λ–»κ²Œ ν–‰λ™ν•˜λŠ”μ§€λ₯Ό κ·œμ •ν•œλ‹€. 각 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ—λŠ” λ³€μˆ˜ 객체(variable object)κ°€ μ—°κ²°λ˜μ–΄ μžˆμœΌλ©°ν•΄λ‹Ή μ»¨ν…μŠ€νŠΈμ—μ„œ μ •μ˜λœ λͺ¨λ“  λ³€μˆ˜μ™€ ν•¨μˆ˜λŠ” 이 객체에 μ‘΄μž¬ν•œλ‹€.

☝️ 이 κ°μ²΄λŠ” μ½”λ“œμ—μ„œ μ ‘κ·Όν•  μˆ˜λŠ” μ—†λ‹€. μ΄λ©΄μ—μ„œ 데이터λ₯Ό λ‹€λ£° λ•Œ 이 객체λ₯Ό μ΄μš©ν•œλ‹€.


2020-04-27-λ³€μˆ˜μ™€-μŠ€μ½”ν”„-λ©”λͺ¨λ¦¬-image-4

κ·Έλ¦Ό 좜처 : πŸ”— μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ™μž‘ 원리 - Poiemaweb


  1. 컨트둀이 μ‹€ν–‰ κ°€λŠ₯ν•œ μ½”λ“œλ‘œ μ΄λ™ν•˜λ©΄, 논리적 μŠ€νƒ ꡬ쑰λ₯Ό κ°€μ§€λŠ” μƒˆλ‘œμš΄ μ‹€ν–‰μ»¨ν…μŠ€νŠΈ μŠ€νƒμ΄ μƒμ„±λœλ‹€. μŠ€νƒμ€ LIFO(Last In First Out, ν›„μž… μ„ μΆœ)의 ꡬ쑰λ₯Όκ°€μ§€λŠ” λ‚˜μ—΄ ꡬ쑰이닀.

  2. μ „μ—­ μ½”λ“œ(Global code)둜 컨트둀이 μ§„μž…ν•˜λ©΄, μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜κ³  μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— μŒ“μΈλ‹€. μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ’…λ£Œλ  λ•Œ(μ›ΉνŽ˜μ΄μ§€μ—μ„œ λ‚˜κ°€κ±°λ‚˜ λΈŒλΌμš°μ €λ₯Ό 닫을 λ•Œ)κΉŒμ§€ μœ μ§€λœλ‹€.

  3. ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜λ©° 직전에 μ‹€ν–‰λœ μ½”λ“œ λΈ”λ‘μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μœ„μ— μŒ“μΈλ‹€.

  4. ν•¨μˆ˜ 싀행이 λλ‚˜λ©΄ ν•΄λ‹Ή ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό νŒŒκΈ°ν•˜κ³  μ§μ „μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ— μ»¨νŠΈλ‘€μ„ λ°˜ν™˜ν•œλ‹€.


μ»¨ν…μŠ€νŠΈμ—μ„œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄, λ³€μˆ˜ 객체에 μŠ€μ½”ν”„ 체인(scope chain)이 λ§Œλ“€μ–΄ 진닀 . μŠ€μ½”ν”„ 체인의 λͺ©μ μ€ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μ ‘κ·Όν•  수 μžˆλŠ” λͺ¨λ“  λ³€μˆ˜μ™€ ν•¨μˆ˜μ— μˆœμ„œλ₯Όμ •ν•˜λŠ” 것이닀.

  1. μ½”λ“œκ°€ μ‹€ν–‰λ˜λŠ” μ»¨ν…μŠ€νŠΈμ˜ λ³€μˆ˜ 객체

  2. ν•΄λ‹Ή μ»¨ν…μŠ€νŠΈλ₯Ό ν¬ν•¨ν•˜λŠ” μ»¨ν…μŠ€νŠΈ(λΆ€λͺ¨ μ»¨ν…μŠ€νŠΈ)

  3. λΆ€λͺ¨μ˜ λΆ€λͺ¨ μ»¨ν…μŠ€νŠΈ

  4. ...

  5. μ „μ—­ μ»¨ν…μŠ€νŠΈ

μ‹λ³„μžλ₯Ό 찾을 λ•Œ 이 μŠ€μ½”ν”„ 체인의 μˆœμ„œλ₯Ό λ”°λΌκ°€λ©΄μ„œ μ‹λ³„μž 이름을 κ²€μƒ‰ν•œλ‹€. λ‚΄λΆ€μ»¨ν…μŠ€νŠΈλŠ” μŠ€μ½”ν”„ 체인을 톡해 μ™ΈλΆ€ μ»¨ν…μŠ€νŠΈ 전체에 μ ‘κ·Ό κ°€λŠ₯ν•˜μ§€λ§Œ, μ™ΈλΆ€ μ»¨ν…μŠ€νŠΈλŠ” λ‚΄λΆ€ μ»¨ν…μŠ€νŠΈμ— λŒ€ν•΄ μ „ν˜€ μ•Œ 수 μ—†λ‹€.

var color = 'blue';
function changeColor() {    var anotherColor = 'red';
    function swapColors() {        var tempColor = anotherColor;        anotherColor = color;        color = tempColor;    }
    swapColors();}
changeColor();console.log(color);

이 μ½”λ“œμ—λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈ, changeColor() 의 둜컬 μ»¨ν…μŠ€νŠΈ, swapColors() 의둜컬 μ»¨ν…μŠ€νŠΈλ‘œ μ„Έ 개의 μ½˜ν…μŠ€νŠΈκ°€ μžˆλ‹€. swapColors λŠ” μžμ‹ μ˜ λ³€μˆ˜ κ°μ²΄μ—μ„œ λ³€μˆ˜λ‚˜ ν•¨μˆ˜ 이름을 κ²€μƒ‰ν•˜κ³  찾지 λͺ»ν•˜λ©΄ μŠ€μ½”ν”„ 체인을 따라 ν•œ 단계 μ”© μ˜¬λΌκ°„λ‹€. ν•˜μ§€λ§Œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ—μ„œλŠ” 둜컬 μ»¨ν…μŠ€νŠΈμ— μ ‘κ·Όν•  수 μ—†λ‹€.

μŠ€μ½”ν”„ 체인 ν™•μž₯#

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인을 ν™•μž₯ν•  수 μžˆλŠ” 방법이 μžˆλ‹€.

  • try-catch 문의 catch 블둝

  • with λ¬Έ

두 λ¬Έμž₯은 μŠ€μ½”ν”„ 체인 μ•žμ— λ³€μˆ˜ 객체λ₯Ό μΆ”κ°€ν•œλ‹€. with 문은 ν•΄λ‹Ή 객체가 μŠ€μ½”ν”„μ²΄μΈμ— μΆ”κ°€λ˜κ³ , catch λ¬Έμ—μ„œλŠ” μ—λŸ¬ 객체λ₯Ό μ„ μ–Έν•˜λŠ” λ³€μˆ˜ 객체가 μƒμ„±λœλ‹€.

function buildUrl() {    var qs = '?debug=true';
    with (location) {        var url = href + qs;    }
    return url;}

μ—¬κΈ°μ„œ href λŠ” with 문이 μΆ”κ°€ν•œ location 객체에 λ“€μ–΄μžˆλŠ” λ³€μˆ˜μ΄λ‹€. with λ¬Έλ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜ url 이 ν•¨μˆ˜μ˜ μ»¨ν…μŠ€νŠΈλ‘œ νŽΈμž…λ˜μ–΄ ν•¨μˆ˜ κ°’μœΌλ‘œ λ°˜ν™˜λ  수 μžˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 블둝 레벨 μŠ€μ½”ν”„#

ES5κΉŒμ§€ var κ°€ λ³€μˆ˜λ₯Ό μ„ μ–Έν•  수 μžˆλŠ” μœ μΌν•œ ν‚€μ›Œλ“œμ˜€μ§€λ§Œ, ES6λΆ€ν„°λŠ” let ν‚€μ›Œλ“œλ₯Ό μ‚¬μš©ν•˜μ—¬ 블둝 레벨 μŠ€μ½”ν”„μ˜ λ³€μˆ˜λ₯Ό μ •μ˜ν•  수 μžˆλ‹€.


ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„(Function-level scope) ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ©° ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μ°Έμ‘°ν•  수 μ—†λ‹€. 즉, ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ”μ§€μ—­ λ³€μˆ˜μ΄λ©° ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λͺ¨λ‘ μ „μ—­ λ³€μˆ˜μ΄λ‹€.

블둝 레벨 μŠ€μ½”ν”„(Block-level scope) λͺ¨λ“  μ½”λ“œ 블둝(ν•¨μˆ˜, if λ¬Έ, for λ¬Έ, while λ¬Έ, try/catch λ¬Έ λ“±) λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” μ½”λ“œ 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ©° μ½”λ“œλΈ”λ‘ μ™ΈλΆ€μ—μ„œλŠ” μ°Έμ‘°ν•  수 μ—†λ‹€. 즉, μ½”λ“œ 블둝 λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 지역 λ³€μˆ˜μ΄λ‹€.

let, const | PoiemaWeb


var λ₯Ό μ‚¬μš©ν•˜μ—¬ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λ₯Ό 가지기 λ•Œλ¬Έμ—, if λ¬Έ, for λ¬Έ, while λ¬Έ λ“±μ˜ 블둝 λ‚΄λΆ€μ—μ„œ μ‚¬μš©λ˜λŠ” λ³€μˆ˜λΌ 할지라도 ν•΄λ‹Ή 블둝이 μ‹€ν–‰λœ μ΄ν›„μ—νŒŒκ΄΄λ˜μ§€ μ•Šκ³  μ‘΄μž¬ν•œλ‹€. (λ‹€λ₯Έ μ–Έμ–΄μ—μ„œλŠ” 일반적으둜 블둝 레벨 μŠ€μ½”ν”„λ‘œ ν•΄λ‹Ή λ³€μˆ˜λŠ”νŒŒκ΄΄λœλ‹€.)

if (true) {    var color = 'blue';}alert(color); // "blue"
for (var i = 0; i < 10; i++) {    doSomething(i);}alert(i); // 10

λ³€μˆ˜ μ„ μ–Έ

var 둜 μ„ μ–Έλœ λ³€μˆ˜λŠ” μžλ™μœΌλ‘œ κ°€μž₯ κ°€κΉŒμš΄ μ»¨ν…μŠ€νŠΈμ— μΆ”κ°€λœλ‹€. ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ”ν•¨μˆ˜μ˜ 둜컬 μ»¨ν…μŠ€νŠΈ, with λ¬Έ λ‚΄λΆ€μ—μ„œλŠ” ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈκ°€ κ°€μž₯ κ°€κΉŒμš΄ μ»¨ν…μŠ€νŠΈμ΄λ‹€. λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜μ§€ μ•Šμ€ 채 μ΄ˆκΈ°ν™” ν•  경우 μžλ™μœΌλ‘œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ— μΆ”κ°€λœλ‹€.

function add(num1, num2) {    var sum = num1 + num2;    return sum;}
var result = add(10, 20);alert(sum); // μœ νš¨ν•œ λ³€μˆ˜κ°€ μ•„λ‹˜
function add(num1, num2) {    sum = num1 + num2; // var ν‚€μ›Œλ“œλ₯Ό μƒλž΅ν•˜μ—¬ μ „μ—­ μ»¨ν…μŠ€νŠΈ    return sum;}
var result = add(10, 20);alert(sum); // 30

μ‹λ³„μž 검색

μ»¨ν…μŠ€νŠΈ μ•ˆμ—μ„œ μ‹λ³„μžλ₯Ό μ°Έμ‘°ν•˜λ € ν•˜λ©΄ μ‹λ³„μžλ₯Ό κ²€μƒ‰ν•˜κ²Œ λ˜λŠ”λ°, 검색은 κ°€μž₯ κ°€κΉŒμš΄ μ»¨ν…μŠ€νŠΈμ—μ„œ μ‹œμž‘ν•˜μ—¬ 이름을 찾으면 검색을 λ©ˆμΆ”κ³  λ³€μˆ˜λ₯Ό μ„€μ •ν•œλ‹€. 찾지 λͺ»ν•˜λ©΄ 검색을 κ³„μ†ν•˜λŠ”λ°, μ „μ—­μ—μ„œλ„ 찾지 λͺ»ν•  경우 μ‹λ³„μžκ°€ μ •μ˜λ˜μ§€ μ•Šμ€ κ²ƒμœΌλ‘œνŒλ‹¨ν•˜κ³  검색을 λ©ˆμΆ˜λ‹€.

var color = 'blue';function getColor() {    return color;}alert(getColor()); // "blue"

μ‹λ³„μžκ°€ 둜컬 μ»¨ν…μŠ€νŠΈμ— μ •μ˜λ˜μ–΄ 있으면, λΆ€λͺ¨ μ»¨ν…μŠ€νŠΈμ— 같은 μ΄λ¦„μ˜ μ‹λ³„μžκ°€μžˆμ–΄λ„ μ°Έμ‘°ν•  수 μ—†λ‹€. μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ λ³€μˆ˜λ₯Ό μ΄μš©ν•  경우 window 객체λ₯Ό μ°Έμ‘°ν•˜λ©΄μ‚¬μš©ν•  수 μžˆλ‹€.

var color = 'blue';
function getColor() {    var color = 'red';    console.log(color);    console.log(window.color);}
getColor();

가비지 μ½œλ ‰μ…˜#

C μ–Έμ–΄μ—μ„œλŠ” λ©”λͺ¨λ¦¬ 관리λ₯Ό μœ„ν•΄ malloc() κ³Ό free() λ₯Ό μ‚¬μš©ν•˜λŠ”λ°, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 객체가 μƒμ„±λ˜μ—ˆμ„ λ•Œ μžλ™μœΌλ‘œ λ©”λͺ¨λ¦¬λ₯Ό ν• λ‹Ήν•˜κ³  μ“Έλͺ¨ μ—†μ–΄μ‘Œμ„ λ•Œ μžλ™μœΌλ‘œν•΄μ œν•˜λŠ” 가비지 μ»¬λ ‰μ…˜μ„ μ‚¬μš©ν•œλ‹€. μ΄λŸ¬ν•œ 가비지 μ»¬λ ‰μ…˜ ν”„λ‘œμ„ΈμŠ€λŠ” 주기적으둜 μ‹€ν–‰λ˜κ³ , νŠΉμ • μ‹œμ μ—μ„œ μ‹œν–‰ν•˜λ„λ‘ 지정할 μˆ˜λ„ μžˆλ‹€.

ν•¨μˆ˜ λ‚΄ 지역 λ³€μˆ˜μ˜ 경우 ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ©΄ λ³€μˆ˜κ°€ μƒμ„±λ˜κ³ , μŠ€νƒμ— λ³€μˆ˜μ˜ 값을 μ €μž₯ν•  λ©”λͺ¨λ¦¬κ°€ ν• λ‹Ήλœλ‹€. ν•¨μˆ˜κ°€ μ’…λ£Œλ˜λ©΄ λ³€μˆ˜κ°€ 더 이상 ν•„μš”ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ 가비지컬렉터가 νšŒμˆ˜ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ μ–΄λ–€ λ³€μˆ˜κ°€ 더 이상 μ‚¬μš©λ˜μ§€ μ•ŠλŠ”μ§€, μ‚¬μš©λ  κ°€λŠ₯성이 μžˆλŠ”μ§€ νŒλ‹¨ν•  수 μžˆλŠ” 방법이 ν•„μš”ν•˜λ‹€.

ν‘œμ‹œν•˜κ³  μ§€μš°κΈ°#

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ 널리 μ“°μ΄λŠ” 가비지 μ»¬λ ‰μ…˜ 방법은 "ν‘œμ‹œν•˜κ³  μ§€μš°κΈ° (mark-and-sweep)"이닀. 가비지 컬렉터가 μž‘λ™ν•˜λ©΄ λ©”λͺ¨λ¦¬μ— μ €μž₯된 λ³€μˆ˜ 전체에 ν‘œμ‹œλ₯Ό 남긴 λ‹€μŒ, μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜μ™€ μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜κ°€ μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜μ—μ„œν‘œμ‹œλ₯Ό μ§€μš΄λ‹€. μ΄λ ‡κ²Œ ν•œ λ’€ ν‘œμ‹œκ°€ 남아 μžˆλŠ” λ³€μˆ˜κ°€ μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜μ™€ λ¬΄κ΄€ν•˜λ―€λ‘œ μ‚­μ œν•΄λ„ μ•ˆμ „ν•˜λ‹€κ³  νŒλ‹¨ν•˜μ—¬, 'λ©”λͺ¨λ¦¬ μ²­μ†Œ'λ₯Ό μ‹€ν–‰ν•΄ νŒŒκ΄΄ν•˜κ³  λ©”λͺ¨λ¦¬λ₯Ό νšŒμˆ˜ν•œλ‹€.

μ°Έμ‘° μΉ΄μš΄νŒ…#

"μ°Έμ‘° μΉ΄μš΄νŒ…(reference counting)"이라고 λΆˆλ¦¬λŠ” 가비지 μ»¬λ ‰μ…˜ 방법도 μžˆλ‹€. λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  μ°Έμ‘° 값이 할당될 λ•Œλ§ˆλ‹€ μ°Έμ‘° 카운트λ₯Ό 1μ”© 늘리고, 값을 μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜μ— λ‹€λ₯Έ 값이 ν• λ‹Ή 될 λ•Œλ§ˆλ‹€ μ°Έμ‘° 카운트λ₯Ό 1μ”© μ€„μ—¬μ„œ, μ°Έμ‘° μΉ΄μš΄νŠΈκ°€ 0이라면 ν•΄λ‹Ή 값에 μ ‘κ·Όν•  방법이 μ—†λ‹€κ³  νŒλ‹¨ν•˜μ—¬ λ©”λͺ¨λ¦¬λ₯Ό νšŒμˆ˜ν•˜λŠ” 방법이닀.

ν•˜μ§€λ§Œ μ΄λŠ” μˆœν™˜ μ°Έμ‘°λΌλŠ” μ‹¬κ°ν•œ λ¬Έμ œκ°€ μžˆλ‹€.

function problem() {    var objectA = new Object();    var objectB = new Object();
    objectA.someOtherObject = objectB;    objectB.anotherObject = objectA;}

이 μ˜ˆμ œμ—μ„œ objectA 와 objectB κ°€ μ„œλ‘œλ₯Ό μ°Έμ‘°ν•˜μ—¬ 각각의 μ°Έμ‘° μΉ΄μš΄νŠΈκ°€ 2인데 , ν•¨μˆ˜ 싀행이 λλ‚œ 뒀에도 μ°Έμ‘° μΉ΄μš΄νŠΈκ°€ 0이 λ˜μ§€ μ•ŠμœΌλ―€λ‘œ 두 λ³€μˆ˜κ°€ 계속 λ©”λͺ¨λ¦¬μ— 남아 λ‚­λΉ„κ°€ λ°œμƒν•œλ‹€.

μ΅μŠ€ν”Œλ‘œλŸ¬ 8κ³Ό 이전 λ²„μ „μ—μ„œ 객체 쀑 일뢀가 C++을 μ‚¬μš©ν•œ μ°Έμ‘° μΉ΄μš΄νŒ… λ°©μ‹μœΌλ‘œκ΅¬ν˜„λ˜μ—ˆκ³  μˆœν™˜ μ°Έμ‘° λ¬Έμ œκ°€ λ°œμƒν–ˆλ‹€.

μˆœν™˜ μ°Έμ‘° 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄μ„œλŠ” ν•΄λ‹Ή 객체λ₯Ό λ‹€ μ‚¬μš©ν•œ 뒀에 λ‘˜ μ‚¬μ΄μ˜ μ—°κ²°μ„λŠμ–΄μ•Ό ν•œλ‹€. null을 ν• λ‹Ήν•˜λ©΄ 연결을 μ œκ±°ν•  수 μžˆλ‹€.

μ„±λŠ₯#

가비지 μ»¬λ ‰μ…˜μ„ μ‹€ν–‰ν•˜λŠ” 타이밍이 μ„±λŠ₯ ν–₯상을 μœ„ν•΄ μ€‘μš”ν•˜λ‹€. 인터넷 μ΅μŠ€ν”Œλ‘œλŸ¬λŠ”λ„ˆλ¬΄ 자주 가비지 컬렉터λ₯Ό μ‹€ν–‰ν•˜μ—¬ μ„±λŠ₯ 문제λ₯Ό μ•ΌκΈ°ν•΄μ™”λ‹€.

λ©”λͺ¨λ¦¬ 관리#

가비지 μ»¬λ ‰μ…˜μ„ μ§€μ›ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° ν™˜κ²½μ—μ„œλŠ” κ°œλ°œμžκ°€ λ©”λͺ¨λ¦¬ 관리λ₯Ό μ‹ κ²½μ“°μ§€μ•Šμ•„λ„ λ˜λ―€λ‘œ νŽΈλ¦¬ν•˜λ‹€. ν•˜μ§€λ§Œ μ›Ή λΈŒλΌμš°μ €μ—μ„œ μ‚¬μš©ν•  수 μžˆλŠ” λ©”λͺ¨λ¦¬λŠ” 일반 λ°μŠ€ν¬ν†± 앱에 λΉ„ν•΄ 맀우 μ μœΌλ―€λ‘œ κ°€λŠ₯ν•œ ν•œ μ΅œμ†Œν•œμ˜ λ©”λͺ¨λ¦¬λ§Œ μ‚¬μš©ν•΄μ•Ό μ„±λŠ₯을 올릴 μˆ˜μžˆλ‹€.

κ°€μž₯ 쒋은 방법은 μ½”λ“œ 싀행에 ν•„μš”ν•œ λ°μ΄ν„°λ§Œ μœ μ§€ν•˜λŠ” 것이닀. ν•„μš”μ—†μ–΄μ§„ λ°μ΄ν„°λŠ” null을 ν• λ‹Ήν•˜μ—¬ μ°Έμ‘°λ₯Ό μ œκ±°ν•˜λŠ” 것이 μ’‹λ‹€. μˆ˜λ™μœΌλ‘œ μ°Έμ‘° μ œκ±°ν•΄μ•Ό ν•  λŒ€μƒμ€μ£Όλ‘œ μ „μ—­ λ³€μˆ˜ 및 μ „μ—­ 객체의 ν”„λ‘œνΌν‹° 인데, 지역 λ³€μˆ˜λŠ” μ»¨ν…μŠ€νŠΈλ₯Ό λΉ μ Έλ‚˜κ°€λŠ”μˆœκ°„μžλ™μœΌλ‘œ μ°Έμ‘°κ°€ μ œκ±°λ˜μ§€λ§Œ, μ „μ—­ λ³€μˆ˜λŠ” μ°Έμ‘°λ₯Ό μ œκ±°ν•˜μ§€ μ•ŠμœΌλ©΄ 계속 λ©”λͺ¨λ¦¬μ— λ‚¨μ•„μžˆκ²Œ λœλ‹€.

☝️ μ°Έμ‘°λ₯Ό μ œκ±°ν•œ μˆœκ°„ ν• λ‹Ήλœ λ©”λͺ¨λ¦¬κ°€ μžλ™μœΌλ‘œ λ°˜ν™˜λ˜λŠ” 것은 μ•„λ‹ˆλ‹€. μ°Έμ‘° 제거λ₯Ό ν•œ 이후에 싀행될 가비지 μ»¬λ ‰μ…˜μ—μ„œ ν•΄λ‹Ή λ©”λͺ¨λ¦¬κ°€ νšŒμˆ˜λœλ‹€.

μš”μ•½#

μžλ°”μŠ€ν¬λ¦½νŠΈ λ³€μˆ˜μ—λŠ” μ›μ‹œ κ°’κ³Ό μ°Έμ‘° κ°’ 두 가지 ν˜•νƒœλ‘œ 값을 μ €μž₯ν•  수 μžˆλ‹€.

μ›μ‹œ κ°’κ³Ό μ°Έμ‘° κ°’μ—λŠ” λ‹€μŒμ˜ νŠΉμ§•μ΄ μžˆλ‹€.

  • μ›μ‹œ 값은 κ³ μ •λœ 크기λ₯Ό 가지며 μŠ€νƒ λ©”λͺ¨λ¦¬μ— μ €μž₯λœλ‹€.

  • μ›μ‹œ 값을 ν•œ λ³€μˆ˜μ—μ„œ λ‹€λ₯Έ λ³€μˆ˜λ‘œ λ³΅μ‚¬ν•˜λ©΄ κ°’ μžμ²΄κ°€ λ³΅μ‚¬λœλ‹€.

  • μ°Έμ‘° 값은 객체이며 νž™ λ©”λͺ¨λ¦¬μ— μ €μž₯λœλ‹€.

  • λ³€μˆ˜μ— μ°Έμ‘° 값을 μ €μž₯ν•˜λ©΄ ν•΄λ‹Ή λ³€μˆ˜λŠ” 객체에 λŒ€ν•œ 참쑰만 μ €μž₯ν•  뿐 객체 자체λ₯Όμ €μž₯ν•˜λŠ” 것은 μ•„λ‹ˆλ‹€.

  • μ°Έμ‘° 값을 ν•œ λ³€μˆ˜μ—μ„œ λ‹€λ₯Έ λ³€μˆ˜λ‘œ λ³΅μ‚¬ν•˜λ©΄ ν•΄λ‹Ή 객체에 λŒ€ν•œ μ°Έμ‘°λ§Œμ„ λ³΅μ‚¬ν•˜λ―€λ‘œ 두 λ³€μˆ˜λŠ” 같은 객체λ₯Ό μ°Έμ‘°ν•œλ‹€.

  • typeof μ—°μ‚°μžλŠ” κ°’μ˜ μ›μ‹œ νƒ€μž…μ„ νŒλ³„ν•˜λ©° instanceof μ—°μ‚°μžλŠ” κ°’μ˜ μ°Έμ‘° νƒ€μž…μ„ νŒλ³„ν•œλ‹€.

μ›μ‹œ κ°’κ³Ό μ°Έμ‘° 값을 가리지 μ•Šκ³  λͺ¨λ“  λ³€μˆ˜λŠ” μŠ€μ½”ν”„λΌκ³  λΆ€λ₯΄κΈ°λ„ ν•˜λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ— μ‘΄μž¬ν•˜λŠ”λ°, μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λ³€μˆ˜κ°€ μ‘΄μž¬ν•˜λŠ” 기간을 κ²°μ •ν•˜λ©° μ–΄λŠ μ½”λ“œκ°€ ν•΄λ‹Ή λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ”μ§€λ„ κ²°μ •ν•œλ‹€.

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ—λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈμ™€ ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈκ°€ μžˆλ‹€.

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ— μ§„μž…ν•  λ•Œλ§ˆλ‹€ μŠ€μ½”ν”„ 체인이 λ§Œλ“€μ–΄μ§€λ©°, μŠ€μ½”ν”„ 체인은 λ³€μˆ˜μ™€ν•¨μˆ˜λ₯Ό κ²€μƒ‰ν•˜λŠ”λ° 쓰인닀.

  • ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈλŠ” ν•΄λ‹Ή μŠ€μ½”ν”„μ— μžˆλŠ” λ³€μˆ˜, ν•΄λ‹Ή μŠ€μ½”ν”„λ₯Ό ν¬ν•¨ν•˜λŠ” μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜, μ „μ—­ μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜μ— λͺ¨λ‘ μ ‘κ·Όν•  수 μžˆλ‹€.

  • μ „μ—­ μ»¨ν…μŠ€νŠΈλŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” λ³€μˆ˜μ™€ ν•¨μˆ˜μ—λ§Œ μ ‘κ·Όν•  수 있으며, 둜컬(ν•¨μˆ˜) μ»¨ν…μŠ€νŠΈμ— μžˆλŠ” 데이터에 μ§μ ‘μ μœΌλ‘œ μ ‘κ·Όν•  μˆ˜λŠ” μ—†λ‹€.

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” λ³€μˆ˜μ— ν• λ‹Ήλœ λ©”λͺ¨λ¦¬λ₯Ό μ–Έμ œ ν•΄μ œν•  수 μžˆλŠ”μ§€ νŒλ‹¨ν•˜λŠ”λ° λ„μ›€μ΄λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μžλ™μœΌλ‘œ 가비지 μ»¬λ ‰μ…˜μ„ μˆ˜ν–‰ν•˜λ―€λ‘œ κ°œλ°œμžκ°€ λ©”λͺ¨λ¦¬ ν• λ‹Ήκ³Ό νšŒμˆ˜μ—ν¬κ²Œ μ‹ κ²½ μ“Έ ν•„μš”λŠ” μ—†λ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 가비지 μ»¬λ ‰μ…˜ 루틴은 λ‹€μŒκ³Ό κ°™λ‹€.

  • 값이 μŠ€μ½”ν”„λ₯Ό λ²—μ–΄λ‚˜λ©΄ μžλ™μœΌλ‘œ ν‘œμ‹œλ˜κ³  λ‹€μŒμ— 가비지 μ»¬λ ‰μ…˜μ„ μ‹€ν–‰ν•  λ•Œ μ‚­μ œλœλ‹€.

  • 주둜 μ“°μ΄λŠ” 가비지 μ»¬λ ‰μ…˜ μ•Œκ³ λ¦¬μ¦˜μ€ "ν‘œμ‹œν•˜κ³  μ§€μš°κΈ°"이닀.

  • λ‹€λ₯Έ μ•Œκ³ λ¦¬μ¦˜μ€ "μ°Έμ‘° μΉ΄μš΄νŒ…"인데 이 방법은 μˆœν™˜ μ°Έμ‘° λ¬Έμ œκ°€ μžˆλ‹€.

  • λ³€μˆ˜μ—μ„œ μ°Έμ‘°λ₯Ό μ œκ±°ν•˜λ©΄ μˆœν™˜ μ°Έμ‘° λ¬Έμ œλ„ ν•΄κ²°ν•  수 있고, 가비지 μ½œλ ‰μ…˜μ—λ„ 도움이 λœλ‹€.

  • 효율적으둜 κ΄€λ¦¬ν•˜κΈ° μœ„ν•΄μ„œλŠ” μ „μ—­ 객체, μ „μ—­ 객체의 ν”„λ‘œνΌν‹°, μˆœν™˜ 참쑰에 λŒ€ν•œμ°Έμ‘°λ₯Ό μ œκ±°ν•΄μ•Ό ν•œλ‹€.

참고자료#

Explaining Value vs. Reference in Javascript

Understanding JavaScript Pass By Value

[μžλ°”μŠ€ν¬λ¦½νŠΈ] new String("")κ³Ό ""(String literal)κ³Ό String("")에 λŒ€ν•˜μ—¬

Execution Context | PoiemaWeb

let, const | PoiemaWeb