16 minute read

CHAPTER1 this๋ผ๋‚˜ ๋ญ๋ผ๋‚˜

YOU DON_T KNOW JS - this

  • ๊ฐ€์žฅ ํ—ท๊ฐˆ๋ฆฌ๋Š” ๋งค์นด๋‹ˆ์ฆ˜ ์ค‘ ํ•˜๋‚˜ this ํ‚ค์›Œ๋“œ
  • this๋Š” ๋ชจ๋“  ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ ๋‚ด์— ์ž๋™์œผ๋กœ ์„ค์ •๋˜๋Š” ํŠน์ˆ˜ํ•œ ์‹๋ณ„์ž
๋ชจ๋“  ๊ธฐ์ˆ ์ด ๊ณ ๋„๋กœ ๋ฐœ์ „ํ•˜๋ฉด ๋งˆ์ˆ ๊ณผ ๊ตฌ๋ณ„ํ•˜๊ธฐ ์–ด๋ ค์›Œ์ง„๋‹ค.

1.1 this๋ฅผ ์™œ?

  • this์˜ ์œ ์šฉํ•จ๊ณผ ์‚ฌ์šฉ ๋™๊ธฐ
  • ๋‹ค์Œ ์ฝ”๋“œ๊ฐ€ โ€˜์–ด๋–ป๊ฒŒโ€™ ์ž‘๋™ํ•˜๋Š”์ง€ ๋ณด๋‹ค, โ€˜์™œโ€™ ์‚ฌ์šฉํ•˜๋Š”์ง€ ๋ณด์ž
  • identify()์™€ speak() ๋‘ ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด๋ณ„๋กœ ๋”ฐ๋กœ๋”ฐ๋กœ ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑํ•  ํ•„์š” ์—†์ด ๋‹ค์ค‘ ์ฝ˜ํ…์ŠคํŠธ ๊ฐ์ฒด์ธ me์™€ you ๋ชจ๋‘์—์„œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
function identify(){
    return this.name.toUpperCase();
}

function speak() {
    var greeting = `Hello, I'm ${identify.call( this )}`;
    console.log( greeting );
}

var me = {
    name: 'Kyle'
};

var you = {
    name: 'Reader'
};

identify.call( me ); // KYLE
identify.call( you ); // READER

speak.call( me ); // Hello, I'm KYLE
speak.call( you ); // Hello, I'm READER
function identify(context){
    return context.name.toUpperCase();
}

function speak(context) {
    var greeting = `Hello, I'm ${ context }`;
    console.log( greeting );
}

identify( you ); // READER
speak( me ); // Hello, I'm KYLE
  • ํ•˜์ง€๋งŒ ์•”์‹œ์ ์ธ ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ํ•จ๊ป˜ ๋„˜๊ธฐ๋Š”Passing Along this ์ฒด๊ณ„๊ฐ€ API ์„ค๊ณ„์ƒ ์ข€ ๋” ๊น”๋”ํ•˜๊ณ  ๋ช…ํ™•ํ•˜๋ฉฐ ์žฌ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฝ๋‹ค.
  • ์‚ฌ์šฉ ํŒจํ„ด์ด ๋ณต์žกํ•ด์งˆ์ˆ˜๋ก ์ฝ˜ํ…์ŠคํŠธ๋ฅผ ๋„˜๊ธฐ๋Š” ๋ฐฉ๋ฒ•์ด ๋” ์ง€์ €๋ถ„ํ•ด์ง„๋‹ค.

1.2 ํ—ท๊ฐˆ๋ฆฌ๋Š” ๊ฒƒ๋“ค

  • ์‚ฌ๋žŒ๋“ค์€ ๋ณดํ†ต ๋‘ ๊ฐ€์ง€์˜ ์˜๋ฏธ๋กœ ํ•ด์„ํ•˜๋Š”๋ฐ ๋‘˜ ๋‹ค ํ‹€๋ ธ๋‹ค.

    1.2.1 ์ž๊ธฐ ์ž์‹ 

  • this๊ฐ€ ํ•จ์ˆ˜ ๊ทธ ์ž์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚จ๋‹ค๋Š” ์˜คํ•ด๋‹ค.

    1.2.2 ์ž์‹ ์˜ ์Šค์ฝ”ํ”„

  • this๋Š” ์–ด๋–ค ์‹์œผ๋กœ๋„ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š”๋‹ค.

1.3 this๋Š” ๋ฌด์—‡์ธ๊ฐ€?

  • this๋Š” ์ž‘์„ฑ ์‹œ์ ์ด ์•„๋‹Œ ๋Ÿฐํƒ€์ž„ ์‹œ์ ์— ๋ฐ”์ธ๋”ฉ ๋˜๋ฉฐ ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋‹น์‹œ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ฝ˜ํ…์ŠคํŠธ๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค.
  • ์–ด๋–ป๊ฒŒ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ–ˆ๋Š๋ƒ์— ๋”ฐ๋ผ ์ •ํ•ด์ง„๋‹ค.
  • ์–ด๋–ค ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ํ™œ์„ฑํ™” ๋ ˆ์ฝ”๋“œActivation Record, ์ฆ‰ ์‹คํ–‰ ์ฝ˜ํ…์ŠคํŠธExecution Context๊ฐ€ ๋งŒ๋“ค์–ด์ง„๋‹ค. ์—ฌ๊ธฐ์—” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ๊ทผ์›(์ฝœ์ŠคํƒCall-Stack)๊ณผ ํ˜ธ์ถœ ๋ฐฉ๋ฒ•, ์ „๋‹ฌ๋œ ์ธ์ž ๋“ฑ์˜ ์ •๋ณด๊ฐ€ ๋‹ด๊ฒจ์žˆ๋‹ค. this ๋ ˆํผ๋Ÿฐ์Šค๋Š” ๊ทธ์ค‘ ํ•˜๋‚˜๋กœ, ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋‹ค์Œ ์žฅ์—์„œ๋Š” this ๋ฐ”์ธ๋”ฉ์„ ๊ฒฐ์ •์ง“๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ๋ถ€Call-Site๋ฅผ ์„ค๋ช…ํ•œ๋‹ค.

CHAPTER2 this๊ฐ€ ์ด๋Ÿฐ ๊ฑฐ๋กœ๊ตฐ!

  • this๋Š” ํ˜ธ์ถœ๋ถ€์—์„œ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
๊ฝƒ, ๊น€์ถ˜์ˆ˜

๋‚ด๊ฐ€ ๊ทธ์˜ ์ด๋ฆ„์„ ๋ถˆ๋Ÿฌ ์ฃผ๊ธฐ ์ „์—๋Š”
๊ทธ๋Š” ๋‹ค๋งŒ
ํ•˜๋‚˜์˜ ๋ชธ์ง“์— ์ง€๋‚˜์ง€ ์•Š์•˜๋‹ค.

๋‚ด๊ฐ€ ๊ทธ์˜ ์ด๋ฆ„์„ ๋ถˆ๋Ÿฌ ์ฃผ์—ˆ์„ ๋•Œ
๊ทธ๋Š” ๋‚˜์—๊ฒŒ๋กœ ์™€์„œ
๊ฝƒ์ด ๋๋‹ค.

2.1 ํ˜ธ์ถœ๋ถ€

  • this ๋ฐ”์ธ๋”ฉ์˜ ๊ฐœ๋…์„ ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € ํ˜ธ์ถœ๋ถ€, ์ฆ‰ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์ฝ”๋“œ๋ถ€ํ„ฐ ํ™•์ธํ•˜๊ณ  โ€˜this๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฒƒโ€™์ด ๋ฌด์—‡์ธ์ง€ ์ฐพ์•„๋ด์•ผ ํ•œ๋‹ค.
function baz() {
    // ํ˜ธ์ถœ ์Šคํƒ: 'baz'
    // ํ˜ธ์ถœ๋ถ€๋Š” ์ „์—ญ ์Šค์ฝ”ํ”„ ๋‚ด๋ถ€
    console.log( "baz" );
    bar(); // <- 'bar'์˜ ํ˜ธ์ถœ๋ถ€
}

function bar() {
    // ํ˜ธ์ถœ ์Šคํƒ: 'baz' -> 'bar'
    // ํ˜ธ์ถœ๋ถ€๋Š” 'baz' ๋‚ด๋ถ€
    console.log( "bar" );
    foo(); // <- 'foo'์˜ ํ˜ธ์ถœ๋ถ€
}

function foo() {
    // ํ˜ธ์ถœ ์Šคํƒ: 'baz' -> 'bar' -> 'foo'
    // ํ˜ธ์ถœ๋ถ€๋Š” 'bar' ๋‚ด๋ถ€
    console.log( "foo" );
}

baz(); // <- 'baz'์˜ ํ˜ธ์ถœ๋ถ€

2.2 ๋‹จ์ง€ ๊ทœ์น™์ผ ๋ฟ

  • 4๊ฐ€์ง€ ๊ทœ์น™

2.2.1 ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ

  • default ๊ทœ์น™
function foo() {
    console.log( this.a );
}

var a = 2;
foo(); // 2
  • ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์ด ์ ์šฉ๋˜์–ด this๋Š” ์ „์—ญ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•œ๋‹ค.

2.2.2 ์•”์‹œ์  ๋ฐ”์ธ๋”ฉimplicit Binding

  • ํ˜ธ์ถœ๋ถ€์— ์ฝ˜ํ…์ŠคํŠธ ๊ฐ์ฒด๊ฐ€ ์žˆ๋Š”์ง€, ์ฆ‰ ๊ฐ์ฒด์˜ ์†Œ์œ Owning/ํฌํ•จContaining ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•˜๋Š” ๊ฒƒ์ด๋‹ค.
function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo // ์•ž์—์„œ ์„ ์–ธํ•œ foo() ํ•จ์ˆ˜๋ฅผ ์ฐธ์กฐ
}

obj.foo(); // 2
  • ํ˜ธ์ถœ๋ถ€๋Š” obj ์ฝ˜ํ…์ŠคํŠธ๋กœ foo()๋ฅผ ์ฐธ์กฐํ•˜๋ฏ€๋กœ obj ๊ฐ์ฒด๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ์ ์— ํ•จ์ˆ˜์˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ โ€˜์†Œ์œ โ€™ํ•˜๊ฑฐ๋‚˜ โ€˜ํฌํ•จโ€™ํ•œ๋‹ค๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.
  • ์•”์‹œ์  ๋ฐ”์ธ๋”ฉ ๊ทœ์น™์— ๋”ฐ๋ฅด๋ฉด ๋ฐ”๋กœ ์ด obj ์ฝ˜ํ…์ŠคํŠธ ๊ฐ์ฒด๊ฐ€ ํ•จ์ˆ˜ ํ˜ธ์ถœ ์‹œ this์— ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
  • ๋‹ค์Œ ์˜ˆ์ œ์ฒ˜๋Ÿผ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ฐธ์กฐ๊ฐ€ ์ฒด์ด๋‹Chaining๋œ ํ˜•ํƒœ๋ผ๋ฉด ์ตœ์ƒ์œ„Top/์ตœํ•˜์œ„Last ์ˆ˜์ค€์˜ ์ •๋ณด๋งŒ ํ˜ธ์ถœ๋ถ€์™€ ์—ฐ๊ด€๋œ๋‹ค.
function foo() {
    console.log( this.a );
}

var obj2 = {
    a: 42,
    foo: foo
};

var obj1 = {
    a:2,
    obj2: obj2
};

obj1.obj2.foo(); // 42

์•”์‹œ์  ์†Œ์‹ค

  • โ€˜์•”์‹œ์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉ ๋œimplicitly Boundโ€™ ํ•จ์ˆ˜์—์„œ ๋ฐ”์ธ๋”ฉ์ด ์†Œ์‹ค๋˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค.
  • strict mode ์—ฌ๋ถ€์— ๋”ฐ๋ผ ์ „์—ญ ๊ฐ์ฒด๋‚˜ undefined ์ค‘ ํ•œ ๊ฐ€์ง€๋กœ ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
function foo() {
    console.log( this.a );
}

var obj = {
    a: 2,
    foo: foo
};

var bar = obj.foo; // ํ•จ์ˆ˜ ๋ ˆํผ๋Ÿฐ์Šค/๋ณ„๋ช…
var a = "์—ฅ, ์ „์—ญ์ด๋„ค!" // 'a' ์—ญ์‹œ ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ
bar(); // "์—ฅ, ์ „์—ญ์ด๋„ค!"
  • bar๋Š” obj์˜ foo๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ๋ณด์ด์ง€๋งŒ ์‹ค์€ foo๋ฅผ ์ง์ ‘ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋˜ ๋‹ค๋ฅธ ๋ ˆํผ๋Ÿฐ์Šค๋‹ค.
  • ๊ฒŒ๋‹ค๊ฐ€ ํ˜ธ์ถœ๋ถ€์—์„œ ๊ทธ๋ƒฅ ํ‰๋ฒ”ํ•˜๊ฒŒ bar()๋ฅผ ํ˜ธ์ถœํ•˜๋ฏ€๋กœ ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์ด ์ ์šฉ๋œ๋‹ค.
  • ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒฝ์šฐ์—” ์ข€ ๋” ์• ๋งคํ•˜๊ฒŒ ์‹คํ–‰๋˜์–ด ์˜ˆ์ƒ์™ธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜จ๋‹ค.
function foo() {
    console.log( this.a );
}

function doFoo(fn) {
    // 'fn'์€ 'foo'์˜ ๋˜ ๋‹ค๋ฅธ ๋ ˆํผ๋Ÿฐ์Šค์ผ ๋ฟ์ด๋‹ค.

    fn(); // <- ํ˜ธ์ถœ๋ถ€
}

var obj = {
    a:2,
    foo:foo
};

var a = "์—ฅ, ์ ์—ญ์ด๋„ค!";  // 'a' ์—ญ์‹œ ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ
doFoo( obj.foo ); // "์—ฅ, ์ „์—ญ์ด๋„ค!"
  • ์ฝœ๋ฐฑ์„ ๋ฐ›์•„ ์ฒ˜๋ฆฌํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ๋‚ด์žฅ ํ•จ์ˆ˜๋ผ๋„ ๊ฒฐ๊ณผ๋Š” ๋งˆ์ฐฌ๊ฐ€์ง€๋‹ค. (์˜ˆ์ œ ์ƒ๋žต)

2.2.3 ๋ช…์‹œ์  ๋ฐ”์ธ๋”ฉ

2.2.4 new ๋ฐ”์ธ๋”ฉ

2.3 ๋ชจ๋“  ๊ฑด ์ˆœ์„œ๊ฐ€ ์žˆ๋Š” ๋ฒ•

2.3.1 this ํ™•์ • ๊ทœ์น™

2.4 ๋ฐ”์ธ๋”ฉ ์˜ˆ์™ธ

2.4.1 this ๋ฌด์‹œ

2.4.2 ๊ฐ„์ ‘ ๋ ˆํผ๋Ÿฐ์Šค

2.4.3 ์†Œํ”„ํŠธ ๋ฐ”์ธ๋”ฉ

2.5 ์–ดํœ˜์  this

  • ES6 ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” 4๊ฐ€์ง€ ํ‘œ์ค€ ๊ทœ์น™ ๋Œ€์‹  ์—๋‘๋ฅธ ์Šค์ฝ”ํ”„Enclosing Scope(ํ•จ์ˆ˜ ๋˜๋Š” ์ „์—ญ)๋ฅผ ๋ณด๊ณ  this๋ฅผ ์•Œ์•„์„œ ๋ฐ”์ธ๋”ฉ ํ•œ๋‹ค.
  • ๋‹ค์Œ์€ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ๋‚˜ํƒ€๋‚ธ ์˜ˆ์ œ๋‹ค.
function foo() {
    // ํ™”์‚ดํ‘œํ•จ์ˆ˜๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
    return (a) => {
        // ์—ฌ๊ธฐ์„œ 'this'๋Š” ์–ดํœ˜์ ์œผ๋กœ 'foo()'์—์„œ ์ƒ์†๋œ๋‹ค.
        console.log( this.a );
    };
}

var obj1 = {
    a: 2
}

var obj2 = {
    a: 3
}

var bar = foo.call( obj1 );
bar.call( obj2 ); // 2, 3์ด ์•„๋‹ˆ๋‹ค!
  • foo() ๋‚ด๋ถ€์—์„œ ์ƒ์„ฑ๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” foo() ํ˜ธ์ถœ ๋‹น์‹œ this๋ฅผ ๋ฌด์กฐ๊ฑด ์–ดํœ˜์ ์œผ๋กœ ํฌ์ฐฉํ•œ๋‹ค. foo()๋Š” obj1์— this๊ฐ€ ๋ฐ”์ธ๋”ฉ ๋˜๋ฏ€๋กœ bar(๋ฐ˜ํ™˜๋œ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ณ€์ˆ˜)์˜ this ์—ญ์‹œ obj1๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค. ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ์–ดํœ˜์  ๋ฐ”์ธ๋”ฉ์€ ์ ˆ๋Œ€๋กœ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์—†๋‹ค.
  • ES6 ์ด์ „์—๋„ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ ๊ธฐ๋Šฅ๊ณผ ํฌ๊ฒŒ ๋‹ค๋ฅด์ง€ ์•Š์€, ๋‚˜๋ฆ„๋Œ€๋กœ ๋งŽ์ด ์“ฐ์ด๋˜ ํŒจํ„ด์ด ์žˆ์—ˆ๋‹ค.
function foo() {
    var self = this; // 'this'๋ฅผ ์–ดํœ˜์ ์œผ๋กœ ํฌ์ฐฉํ•œ๋‹ค.
    setTimeout( function(){
        console.log( self.a );
    }, 100 );
}

var obj = {
    a: 2
};

foo.call( obj ); // 2
  • this ์Šคํƒ€์ผ์˜ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ๊ผญ ๋‹ค์Œ ๋‘ ๊ฐ€์ง€ ์ค‘ ํ•˜๋‚˜๋งŒ ์„ ํƒํ•˜์ž.
    1. ์˜ค์ง ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๊ฐ€์‹์ ์ธ this ์Šคํƒ€์ผ์˜ ์ฝ”๋“œ๋Š” ์ ‘์–ด๋‘”๋‹ค.
    2. ํ•„์š”ํ•˜๋ฉด bind()๊นŒ์ง€ ํฌํ•จํ•˜์—ฌ ์™„์ „ํ•œ this ์Šคํƒ€์ผ์˜ ์ฝ”๋“œ๋ฅผ ๊ตฌ์‚ฌํ•˜๋˜ self = this๋‚˜ ํ™”์‚ดํ‘œ ํ•จ์ˆ˜ ๊ฐ™์€ ์†Œ์œ„ โ€˜์–ดํœ˜์  thisโ€™๊ผผ์ˆ˜๋Š” ์‚ผ๊ฐ€์•ผ ํ•œ๋‹ค.
    3. ๋‘ ์Šคํƒ€์ผ ๋ชจ๋‘ ์ ์ ˆํžˆ ํ˜ผ์šฉํ•˜์—ฌ ํšจ์œจ์ ์ธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ•  ์ˆ˜๋„ ์žˆ๊ฒ ์ง€๋งŒ ๋™์ผ ํ•จ์ˆ˜ ๋‚ด์—์„œ ๋˜‘๊ฐ™์€ ๊ฒƒ์„ ์ฐพ๋Š”๋ฐ ์„œ๋กœ ๋‹ค๋ฅธ ์Šคํƒ€์ผ์ด ์„ž์—ฌ ์žˆ์œผ๋ฉด ๊ด€๋ฆฌ๋„ ์ž˜ ์•ˆ๋˜๊ณ  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฒœ์žฌ๊ฐ€ ์•„๋‹Œ ์ด์ƒ ์ดํ•ดํ•˜๊ธฐ ๊ณค๋ž€ํ•œ ๊ณจ์นซ๋ฉ์ด ์ฝ”๋“œ๋กœ ๋‚จ๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค.

2.6 ์ •๋ฆฌํ•˜๊ธฐ

  • ํ•จ์ˆ˜ ์‹คํ–‰์— ์žˆ์–ด์„œ this ๋ฐ”์ธ๋”ฉ์€ ํ•จ์ˆ˜์˜ ์ง์ ‘์ ์ธ ํ˜ธ์ถœ๋ถ€์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง„๋‹ค. ์ผ๋‹จ ํ˜ธ์ถœ๋ถ€๋ฅผ ์‹๋ณ„ํ•œ ํ›„ ๋‹ค์Œ 4๊ฐ€์ง€ ๊ทœ์น™์„ ์—ด๊ฑฐํ•œ ์šฐ์„ ์ˆœ์œ„์— ๋”ฐ๋ผ ์ ์šฉํ•œ๋‹ค.
    1. new๋กœ ํ˜ธ์ถœํ–ˆ๋‹ค๋ฉด ์ƒˆ๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
    2. call์ด๋‚˜ apply ๋˜๋Š” bind๋กœ ํ˜ธ์ถœ๋๋‹ค๋ฉด ์ฃผ์–ด์ง„ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
    3. ํ˜ธ์ถœ์˜ ์ฃผ์ฒด์ธ ์ฝ˜ํ…์ŠคํŠธ ๊ฐ์ฒด๋กœ ํ˜ธ์ถœ๋๋‹ค๋ฉด ๋ฐ”๋กœ ์ด ์ฝ˜ํ…์ŠคํŠธ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
    4. ๊ธฐ๋ณธ ๋ฐ”์ธ๋”ฉ์—์„œ ์—„๊ฒฉ ๋ชจ๋“œ๋Š” undefined, ๊ทธ ๋ฐ–์—” ์ „์—ญ ๊ฐ์ฒด๋กœ ๋ฐ”์ธ๋”ฉ ๋œ๋‹ค.
  • this ๋ฐ”์ธ๋”ฉ์„ ์•ˆ์ „ํ•˜๊ฒŒ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด โˆ… = Object.create(null)์ฒ˜๋Ÿผ DMZ ๊ฐ์ฒด๋ฅผ ์ž๋ฆฌ ๋ผ์›€ ๊ฐ’์œผ๋กœ ๋ฐ”๊ฟ”๋„ฃ์–ด ๋œปํ•˜์ง€ ์•Š์€ ๋ถ€์ˆ˜ ํšจ๊ณผ๊ฐ€ ์ „์—ญ ๊ฐ์ฒด์—์„œ ๋ฐœ์ƒํ•˜์ง€ ์•Š๊ฒŒ ํ•œ๋‹ค.
  • ES6 ํ™”์‚ดํ‘œ ํ•จ์ˆ˜๋Š” ํ‘œ์ค€ ๋ฐ”์ธ๋”ฉ ๊ทœ์น™์„ ๋ฌด์‹œํ•˜๊ณ  ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋กœ this๋ฅผ ๋ฐ”์ธ๋”ฉ ํ•œ๋‹ค. ์ฆ‰, ์—๋‘๋ฅธ ํ•จ์ˆ˜ ํ˜ธ์ถœ๋กœ๋ถ€ํ„ฐ ์–ด๋–ค ๊ฐ’์ด๋“  this ๋ฐ”์ธ๋”ฉ์„ ์ƒ์†ํ•œ๋‹ค. ์ด๋Š” ES6 ์ด์ „ ์‹œ์ ˆ self = this ๊ตฌ๋ฌธ์„ ๋Œ€์ฒดํ•œ ์žฅ์น˜๋‹ค.

  • #ref: ๊ฐ™์€ ์ฑ…, ๋” ์ž˜ ์ •๋ฆฌ๋œ ๊ธ€ - https://jeonghwan-kim.github.io/2017/10/22/js-context-binding.html

CHAPTER3 ๊ฐ์ฒด

  • ๊ฐ์ฒด๋Š” ์ •ํ™•ํžˆ ๋ฌด์—‡์ด๊ณ  this๋ฅผ ๋ฐ”์ธ๋”ฉํ•  ๋•Œ ์™œ ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌ์ผœ์•ผ ํ• ๊นŒ?

3.1 ๊ตฌ๋ฌธ

  • ๊ฐ์ฒด๋Š” ์„ ์–ธ์ Declarative(๋ฆฌํ„ฐ๋ŸดLiteral) ํ˜•์‹๊ณผ ์ƒ์„ฑ์ž ํ˜•์‹, ๋‘ ๊ฐ€์ง€๋กœ ์ •์˜ํ•œ๋‹ค.
  • ๋ฆฌํ„ฐ๋Ÿด ํ˜•์‹
var myObj = {
    key: value
    // ...
}
  • ์ƒ์„ฑ์ž ํ˜•์‹
var myObj = new Object();
myObj.key = value;

3.2 ํƒ€์ž…

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๊ฐ์ฒด์˜ 7๊ฐœ ์ฃผ์š” ํƒ€์ž…(๋ช…์„ธ์„œ์—” โ€˜์–ธ์–ด ํƒ€์ž…Language Typeโ€˜์ด๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค)์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
1. null
2. undefined
3. boolean
4. number
5. string
6. object
7. symbol
  • โ€˜๋‹จ์ˆœ ์›์‹œ ํƒ€์ž…Simple Primitive(string, number, null, undefined)โ€™์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๋‹ค.
  • ๋ฐ˜๋ฉด โ€˜๋ณตํ•ฉ ์›์‹œ ํƒ€์ž…Complex Primitiveโ€˜์ด๋ผ๋Š” ๋…ํŠนํ•œ ๊ฐ์ฒด ํ•˜์œ„ ํƒ€์ž…Sub Type์ด ์žˆ๋‹ค. function์€ ๊ฐ์ฒด(์ •ํ™•ํžˆ๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒดCallable Object)์˜ ํ•˜์œ„ ํƒ€์ž…์ด๋‹ค. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํ•จ์ˆ˜๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ๋Š” (ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ํŠน์„ฑ์ด ๊ณ ์ •๋œ) ๊ฐ์ฒด์ด๋ฏ€๋กœ โ€˜์ผ๊ธ‰First Classโ€˜์ด๋ฉฐ ์—ฌํƒ€์˜ ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ๋˜‘๊ฐ™์ด ์ทจ๊ธ‰๋œ๋‹ค.
  • ๋ฐฐ์—ด ์—ญ์‹œ ์ถ”๊ฐ€ ๊ธฐ๋Šฅ์ด ๊ตฌํ˜„๋œ ๊ฐ์ฒด์˜ ์ผ์ข…์ด๋‹ค. ๋‹ค๋ฅธ ์ผ๋ฐ˜ ๊ฐ์ฒด๋ณด๋‹ค ์ข€ ๋” ์กฐ์ง์ ์œผ๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๊ตฌ์„ฑ๋˜๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.

3.2.1 ๋‚ด์žฅ ๊ฐ์ฒด

  • ๋‚ด์žฅ ๊ฐ์ฒด๋ผ๊ณ  ๋ถ€๋ฅด๋Š” ๊ฐ์ฒด ํ•˜์œ„ ํƒ€์ž…๋„ ์žˆ๋‹ค.
  1. String
  2. Number
  3. Boolean
  4. Object
  5. Function
  6. Array
  7. Date
  8. RegExp
  9. Error
  • ์ด๋“ค์€ ๋‹จ์ง€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋‚ด์žฅ ํ•จ์ˆ˜์ผ ๋ฟ ๊ฐ๊ฐ ์ƒ์„ฑ์žConstructor๋กœ ์‚ฌ์šฉ๋˜์–ด ์ฃผ์–ด์ง„ ํ•˜์œ„ ํƒ€์ž…์˜ ์ƒˆ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.
var strPrimitive = 'I am string!';
typeof strPrimitive; // "string"
strPrimitive instanceof String // false

var strObject = new String('I am string!');
typeof strObject; // "object"
strObject instanceof String; // true

// ๊ฐ์ฒด ํ•˜์œ„ ํƒ€์ž…์„ ํ™•์ธํ•œ๋‹ค.
Object.prototype.toString.call( strObject ); // [Object String]
  • Object.prototype.toString๋ถ€๋ถ„์€ toString() ๋ฉ”์„œ๋“œ์˜ ๊ธฐ๋ณธ ๊ตฌํ˜„์ฒด๋ฅผ ๋นŒ๋ ค์„œ ๋‚ด๋ถ€ ํ•˜์œ„ ํƒ€์ž…์„ ์กฐ์‚ฌํ•œ๋‹ค. ๊ทธ ๊ฒฐ๊ณผ strObject๊ฐ€ String ์ƒ์„ฑ์ž์— ์˜ํ•ด ๋งŒ๋“ค์–ด์ง„ ๊ฐ์ฒด์ž„์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

  • ์›์‹œ ๊ฐ’์€ ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ์›์‹œ ๋ฆฌํ„ฐ๋ŸดPrimitive Literal์ด๋ฉฐ ๋ถˆ๋ณ€๊ฐ’Immutable Value์ด๋‹ค. ๋ฌธ์ž ๊ฐœ์ˆ˜๋ฅผ ์„ธ๋Š” ๋“ฑ ๋ฌธ์ž๋ณ„๋กœ ์ ‘๊ทผํ•  ๋•Œ์—” String ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.
  • ๋‹คํ–‰์ด๋„ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ ์ž๋™ ๊ฐ•์ œ๋ณ€ํ™˜Coerceํ•˜๋ฏ€๋กœ ๋ช…์‹œ์ ์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•  ์ผ์€ ๊ฑฐ์˜ ์—†๋‹ค. ๋ฆฌํ„ฐ๋Ÿด ํ˜•์‹์„ ์‚ฌ์šฉํ•˜๋ผ๊ณ  ์ ๊ทน ๊ถŒ์žฅํ•œ๋‹ค.
var strPrimitive = 'I am string!';
console.log( strPrimitive.length );  // 13
console.log( strPrimitive.charAt(3) ); // "m"
  • 42.359.toFixed( 2 )์™€ ๊ฐ™์ด ์ˆซ์ž ๋ฆฌํ„ฐ๋Ÿด 42์— ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•ด๋„ new Number( 42 ) ๊ฐ์ฒด ๋ž˜ํผ๋กœ ๊ฐ•์ œ๋ณ€ํ™˜๋˜๊ณ  ๋ถˆ๋ฆฌ์–ธ ์›์‹œ ๊ฐ’๋„ Boolean ๊ฐ์ฒด๋กœ ๋ฐ”๋€๋‹ค.
  • ๊ฐ์ฒด ๋ž˜ํผ ํ˜•์‹์ด ์—†๋Š” null๊ณผ undefined๋Š” ๊ทธ ์ž์ฒด๋กœ ์œ ์ผ ๊ฐ’์ด๋‹ค. ๋ฐ˜๋Œ€๋กœ Date๊ฐ’์€ ๋ฆฌํ„ฐ๋Ÿด ํ˜•์‹์ด ์—†์–ด์„œ ๋ฐ˜๋“œ์‹œ ์ƒ์„ฑ์ž ํ˜•์‹์œผ๋กœ ์ƒ์„ฑํ•ด์•ผ ํ•œ๋‹ค.
  • Objects, Arrays, Functions, RegExps๋Š” ํ˜•์‹(๋ฆฌํ„ฐ๋Ÿด/์ƒ์„ฑ์ž)๊ณผ ๋ฌด๊ด€ํ•˜๊ฒŒ ๋ชจ๋‘ ๊ฐ์ฒด๋‹ค.
  • Error๊ฐ์ฒด๋Š” ์˜ˆ์™ธ๊ฐ€ ๋˜์ ธ์ง€๋ฉด ์•Œ์•„์„œ ์ƒ์„ฑ๋˜๋‹ˆ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์„ฑํ•  ์ผ์€ ๋“œ๋ฌผ๋‹ค.

3.3 ๋‚ด์šฉ Contents

  • ๊ฐ์ฒด๋Š” ํŠน์ •ํ•œ ์œ„์น˜์— ํ”„๋กœํผํ‹ฐ๋กœ Contents๊ฐ€ ์ฑ„์›Œ์ง„๋‹ค.

3.3.1 ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ๋ช…

  • ES6๋ถ€ํ„ฐ๋Š” ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ๋ช…Computed Property Names์ด๋ผ๋Š” ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋๋Š”๋ฐ, ๊ฐ์ฒด ๋ฆฌํ„ฐ๋Ÿด ์„ ์–ธ ๊ตฌ๋ฌธ์˜ ํ‚ค ์ด๋ฆ„ ๋ถ€๋ถ„์— ํ•ด๋‹น ํ‘œํ˜„์‹์„ ๋„ฃ๊ณ  [ ]๋กœ ๊ฐ์‹ธ๋ฉด ๋œ๋‹ค.
var prefix = "foo";
var myObject = {
    [prefix + "bar"]: "hello",
    [prefix + "baz"]: "world"
};
myObject["foobar"]; // hello
myObject["foobaz"]; // world
  • ๊ณ„์‚ฐ๋œ ํ”„๋กœํผํ‹ฐ๋ช…์€ ES6 ์‹ฌ๋ณผ์—์„œ ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ ์‹ถ๋‹ค.
  • ์‹ฌ๋ณผ์€ ์ƒˆ๋กœ์šด ์›์‹œ ๋ฐ์ดํ„ฐ ํƒ€์ž…์œผ๋กœ ๋ถˆ๋ถ„๋ช…ํ•˜๊ณ  ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ ๊ฐ’(๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๋ฌธ์ž์—ด ๊ฐ’)์„ ๊ฐ€์ง„๋‹ค. ์‹ฌ๋ณผ์˜ ์‹ค์ œ ๊ฐ’(์ด๋ก ์ ์œผ๋กœ๋Š” ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„๋งˆ๋‹ค ์ œ๊ฐ๊ฐ์ผ ์ˆ˜ ์žˆ๋‹ค)์„ ์ง์ ‘ ๋‹ค๋ฃฐ ์ผ์€ ๊ฑฐ์˜ ์—†์œผ๋ฏ€๋กœ Symbol.Something ๊ฐ™์€ ์‹ฌ๋ณผ๋ช…์„ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
var myObject = {
    [Symbol.Something]: "hello wolrd"
}

3.3.2 ํ”„๋กœํผํ‹ฐ vs ๋ฉ”์„œ๋“œ

  • ํ•จ์ˆ˜๋Š” ๊ฒฐ์ฝ” ๊ฐ์ฒด์— ์†ํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ฉฐ, ๊ฐ์ฒด ๋ ˆํผ๋Ÿฐ์Šค๋กœ ์ ‘๊ทผํ•œ ํ•จ์ˆ˜๋ฅผ ๊ทธ๋ƒฅ ๋ฉ”์„œ๋“œ๋ผ ์นญํ•˜๋Š” ๊ฑด ๊ทธ ์˜๋ฏธ๋ฅผ ์ง€๋‚˜์น˜๊ฒŒ ํ™•๋Œ€ํ•ด ํ•ด์„ํ•œ ๊ฒƒ์ด๋‹ค.

3.3.3 ๋ฐฐ์—ด

  • ๋ฐฐ์—ด์€ ์ˆซ์ž ์ธ๋ฑ์‹ฑ, ์ฆ‰ ์ธ๋ฑ์Šค๋ผ๋Š” ์–‘์ˆ˜๋กœ ํ‘œ๊ธฐ๋œ ์œ„์น˜์— ๊ฐ’์„ ์ €์žฅํ•œ๋‹ค.
  • ์ธ๋ฑ์Šค๋Š” ์–‘์ˆ˜์ง€๋งŒ ๋ฐฐ์—ด ์ž์ฒด๋Š” ๊ฐ์ฒด์—ฌ์„œ ๋ฐฐ์—ด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์ธ๋ฑ์Šค๋ฅผ ์“ฐ์ง€ ์•Š๊ณ  ์ผ๋ฐ˜์ ์ธ ํ‚ค/๊ฐ’ ๊ฐ์ฒด๋กœ ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์ง€๋งŒ ์ข‹์€ ์ƒ๊ฐ์€ ์•„๋‹ˆ๋‹ค.

3.3.4 ๊ฐ์ฒด ๋ณต์‚ฌ

  • ๊ฐ์ฒด ๋ณต์‚ฌ์—๋Š” ์–•์€ ๋ณต์‚ฌShallow Copy, ๊นŠ์€ ๋ณต์‚ฌDeep Copy๊ฐ€ ์žˆ๋‹ค.
  • ์–•์€ ๋ณต์‚ฌ๋ฅผ ํ•  ๊ฒฝ์šฐ ํ™˜ํ˜• ์ฐธ์กฐCircular Reference ํ˜•ํƒœ๊ฐ€ ๋˜์–ด ๋ฌดํ•œ ๋ณต์‚ฌ์˜ ๊ตฌ๋ ํ……์ด์— ๋น ์งˆ ์ˆ˜ ์žˆ๋‹ค.
  • ๊นŠ์€ ๋ณต์‚ฌ ๋ฐฉ๋ฒ•์ธ โ€˜JSON-Safe ๊ฐ์ฒดโ€™๋Š” ์‰ฝ๊ฒŒ ๋ณต์‚ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•˜๋‚˜์˜ ๋Œ€์•ˆ์ด ๋  ์ˆ˜๋Š” ์žˆ๋‹ค.
  • ํ•œํŽธ, ์–•์€ ๋ณต์‚ฌ๋Š” ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๊ณ  ๋ณ„๋‹ค๋ฅธ ์ด์Šˆ๊ฐ€ ์—†๊ธฐ์— ES6๋ถ€ํ„ฐ๋Š” Object.assign() ๋ฉ”์„œ๋“œ๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

3.3.5 ํ”„๋กœํผํ‹ฐ ์„œ์ˆ ์ž

  • ES5๋ถ€ํ„ฐ ๋ชจ๋“  ํ”„๋กœํผํ‹ฐ๋Š” ํ”„๋กœํผํ‹ฐ ์„œ์ˆ ์žProperty Descriptor๋กœ ํ‘œํ˜„๋œ๋‹ค.
var myObject = {
    a: 2
};
Object.getOwnPropertyDescriptor( myObject, "a" );
// {
// value: 2,
// writable: true,
// enumerable: true,
// configurable: true
// }
  • ํ‰๋ฒ”ํ•œ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ a์˜ ํ”„๋กœํผํ‹ฐ ์„œ์ˆ ์ž(๋˜๋Š” ๋ฐ์ดํ„ฐ ์„œ์ˆ ์ž)๋ฅผ ์กฐํšŒํ•ด๋ณด๋‹ˆ writable, enumerable, configurable์˜ ์„ธ ๊ฐ€์ง€ ํŠน์„ฑ์ด ๋” ์žˆ๋‹ค.
  • Object.defineProperty()๋กœ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ์˜ ํŠน์„ฑ์„ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.(configurable์ด true์ผ ๋•Œ๋งŒ ๊ฐ€๋Šฅ)
var myObject = {};
Object.defineProperty( myObject, "a", {
    value: 2,
    writable: true,
    enumerable: true,
    configurable: true
} );
myObject.a; // 2
  • ์“ฐ๊ธฐ๊ฐ€๋Šฅ/์„ค์ •๊ฐ€๋Šฅ/์—ด๊ฑฐ๊ฐ€๋Šฅ ํŠน์„ฑ์— ๋”ฐ๋ผ ํ”„๋กœํผํ‹ฐ์˜ ์„ฑ๊ฒฉ์ด ๋ฐ”๋€๋‹ค.

3.3.6 ๋ถˆ๋ณ€์„ฑ

  • ํ”„๋กœํผํ‹ฐ/๊ฐ์ฒด๊ฐ€ ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๊ฒŒ ํ•ด์•ผ ํ•  ๊ฒฝ์šฐ ES5๋ถ€ํ„ฐ ์ด๋Ÿฐ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์ผ ์ œ๊ณตํ•˜์ง€๋งŒ, ์–•์€ ๋ถˆ๋ณ€์„ฑShallow Immutability๋งŒ ์ง€์›ํ•œ๋‹ค. ์ฆ‰, ๊ฐ์ฒด ์ž์‹ ๊ณผ ์ง์† ํ”„๋กœํผํ‹ฐ ํŠน์„ฑ๋งŒ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค ๋ฟ ๋‹ค๋ฅธ ๊ฐ์ฒด(๋ฐฐ์—ด, ๊ฐ์ฒด, ํ•จ์ˆ˜)๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ๋ ˆํผ๋Ÿฐ์Šค๊ฐ€ ์žˆ์„ ๋•Œ ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋‚ด์šฉ๊นŒ์ง€ ๋ถˆ๋ณ€์œผ๋กœ ๋งŒ๋“ค์ง€๋Š” ๋ชปํ•œ๋‹ค.
myImmutableObject.foo; // [1,2,3]
myImmutableObject.foo.push( 4 );
myImmutableObject.foo; // [1,2,3,4]
  • foo๋ฅผ ๋ถ„๋ณ€ ๊ฐ์ฒด๋กœ ๋ฐ”๊พธ๋ ค๋ฉด ์•„๋ž˜์˜ ๋ฐฉ๋ฒ•์ด ์žˆ๋‹ค.
    1. ๊ฐ์ฒด ์ƒ์ˆ˜
  • writable:false์™€ configuration:false๋ฅผ ๊ฐ™์ด ์“ฐ๋ฉด ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์ˆ˜์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋‹ค.
var myObject = {};
Object.defineProperty( myObject, "FAVORITE_NUMBER", {
    value: 42,
    writable: false,
    configurable: false
});
  1. ํ™•์žฅ ๊ธˆ์ง€
    • ๊ฐ์ฒด์— ๋”๋Š” ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๊ฒŒ ์ฐจ๋‹จํ•˜๊ณ  ํ˜„์žฌ ํ”„๋กœํผํ‹ฐ๋Š” ์žˆ๋Š” ๊ทธ๋Œ€๋กœ ๋†”๋‘๊ณ  ์‹ถ์„ ๋•Œ Object.preventExtensions()๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
var myObject = {
    a: 2
};
Object.preventExtensions( myObject );

myObject.b = 3;
myObject.b; // undefined
  • ๋น„์—„๊ฒฉ ๋ชจ๋“œ์—์„  ํ”„๋กœํผํ‹ฐ b๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ ์กฐ์šฉํžˆ ์‹คํŒจํ•˜๊ณ  ์—„๊ฒฉ ๋ชจ๋“œ์—์„œ๋Š” TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  1. ๋ด‰์ธ
    • Object.seal()๋Š” ๋ด‰์ธ๋œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์ฆ‰, ์–ด๋–ค ๊ฐ์ฒด์— ๋Œ€ํ•ด Object.preventExtensions()๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ํ”„๋กœํผํ‹ฐ๋ฅผ ์ „๋ถ€ configurable:false ์ฒ˜๋ฆฌํ•œ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์—†๊ณ  ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ๋ฅผ ์žฌ์„ค์ •ํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•  ์ˆ˜๋„ ์—†๋‹ค. ๋ฌผ๋ก  ๊ฐ’์„ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.
  2. ๋™๊ฒฐ
    • Object.freeze()๋Š” ๊ฐ์ฒด๋ฅผ ๊ฝ๊ฝ ์–ผ๋ฆฐ๋‹ค. ์•ž์—์„œ ์„ค๋ช…ํ•œ Object.seal()์„ ์ ์šฉํ•˜๊ณ  โ€˜๋ฐ์ดํ„ฐ ์ ‘๊ทผ์žData Accessorโ€™ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ชจ๋‘ writable:false ์ฒ˜๋ฆฌํ•ด์„œ ๊ฐ’๋„ ๋ชป ๋ฐ”๊พธ๊ฒŒ ํ•œ๋‹ค.
    • ๋™๊ฒฐ์€ ๊ฐ€์žฅ ๋†’์€ ๋‹จ๊ณ„์˜ ๋ถˆ๋ณ€์„ฑ์„ ์ ์šฉํ•œ ๊ฒƒ์œผ๋กœ ๊ฐ์ฒด์™€ ์ง์† ํ”„๋กœํผํ‹ฐ์— ์–ด๋–ค ๋ณ€๊ฒฝ๋„ ์›์ฒœ ๋ด‰์‡„ํ•œ๋‹ค.

3.3.7 [[Get]]

  • ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๊ธฐ๊นŒ์ง€์˜ ์„ธ๋ถ€ ๊ณผ์ •์€ ๋ฏธ๋ฌ˜ํ•˜๋ฉด์„œ๋„ ์ค‘์š”ํ•˜๋‹ค.
var myObject = {
    a: 2
};
myObject.a; // 2
  • ๋ช…์„ธ์— ๋”ฐ๋ฅด๋ฉด ์‹ค์ œ๋กœ ์ด ์ฝ”๋“œ๋Š” myObject์— ๋Œ€ํ•ด [[Get]] ์—ฐ์‚ฐ์„ ํ•œ๋‹ค. ( [Get] ๊ฐ™์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ )
  • ๊ธฐ๋ณธ์œผ๋กœ [[Get]] ์—ฐ์‚ฐ์€ ์ฃผ์–ด์ง„ ์ด๋ฆ„์˜ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋จผ์ € ์ฐพ์•„๋ณด๊ณ  ์žˆ์œผ๋ฉด ๊ทธ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ํ”„๋กœํผํ‹ฐ๋ฅผ ์ฐพ์•„๋ณด๊ณ  ์—†์œผ๋ฉด [[Get]] ์—ฐ์‚ฐ ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ [[Prototype]] ์—ฐ์‡„ ์ˆœํšŒ๋ฅผ ํ•˜๊ฒŒ ๋œ๋‹ค.
  • ์ฃผ์–ด์ง„ ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์–ด๋–ป๊ฒŒ ํ•ด๋„ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฉด [[Get]] ์—ฐ์‚ฐ์€ undefined๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
var myObject = {
    a: 2
};
myObject.b; // undefined
  • ์‹๋ณ„์ž๋ช…์œผ๋กœ ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ๋• ์ž‘๋™ ๋ฐฉ์‹์ด ๋‹ค๋ฅด๋‹ค. ํ•ด๋‹นํ•˜๋Š” ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„ ๋‚ด์— ์—†๋Š” ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•˜๋ฉด ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ์ฒ˜๋Ÿผ undefined๊ฐ€ ๋ฐ˜ํ™˜๋˜์ง€ ์•Š๊ณ  ReferenceError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
var myObject = {
    a: undefined
};
myObject.a; // undefined
myObject.b; // undefined
  • ๊ฐ’๋งŒ ๋ด์„œ๋Š” ๋‘˜ ๋‹ค undefined๋ผ ๋ถ„์‚ฐ์ด ์•ˆ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๋‚ด๋ถ€์ ์œผ๋กœ [[Get]] ์—ฐ์‚ฐ์„ ์ˆ˜ํ–‰ํ•  ํ…Œ๋‹ˆ ๋Œ€์ฒด๋กœ myObject.b๊ฐ€ myObject.a๋ณด๋‹ค โ€˜๋” ์ผ์„ ๋งŽ์ด ํ•œ๋‹คโ€™๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค. ์ด๋ฅผ ๊ตฌ๋ถ„ํ•˜๋ ค๋ฉด hasOwnProperty ๋ฉ”์„œ๋“œ๋ฅผ ํ†ตํ•ด ์•Œ ์ˆ˜ ์žˆ๋‹ค.

3.3.8 [[Put]]

  • ์–ธ๋œป ๋ณด๊ธฐ์— ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ํ• ๋‹นํ•˜๋Š” ์ผ์€ ๊ทธ์ € [[Put]]์„ ํ˜ธ์ถœํ•˜์—ฌ ์ฃผ์–ด์ง„ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์„ธํŒ…/์ƒ์„ฑํ•˜๋Š” ์ผ์ด ์ „๋ถ€์ผ ๋“ฏ์‹ถ์ง€๋งŒ ์‹ค์ œ๋กœ๋Š” ์ข€ ๋ณต์žกํ•˜๋‹ค.
  • [[Put]]์„ ์‹คํ–‰ํ•˜๋ฉด ์ฃผ์–ด์ง„ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ๋“ฑ ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ์š”์†Œ์— ๋”ฐ๋ผ ์ดํ›„ ์ž‘๋™ ๋ฐฉ์‹์ด ๋‹ฌ๋ผ์ง„๋‹ค. [[Put]] ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ์ด๋ฏธ ์กด์žฌํ•˜๋Š” ํ”„๋กœํผํ‹ฐ์— ๋Œ€ํ•ด ๋Œ€๋žต ๋‹ค์Œ์˜ ํ™•์ธ ์ ˆ์ฐจ๋ฅผ ๋ฐŸ๋Š”๋‹ค.
    1. ํ”„๋กœํผํ‹ฐ๊ฐ€ ์ ‘๊ทผ ์„œ์ˆ ์žAccessor Descriptor์ธ๊ฐ€? ๋งž์œผ๋ฉด ์„ธํ„ฐ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
    2. ํ”„๋กœํผํ‹ฐ๊ฐ€ writable:false์ธ ๋ฐ์ดํ„ฐ ์„œ์ˆ ์‚ฌData Descriptor์ธ๊ฐ€? ๋งž์œผ๋ฉด ๋น„์—„๊ฒฉ ๋ชจ๋“œ์—์„œ ์กฐ์šฉํžˆ ์‹คํŒจํ•˜๊ณ  ์—„๊ฒฉ ๋ชจ๋“œ๋Š” TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
    3. ์ด์™ธ์—๋Š” ํ”„๋กœํผํ‹ฐ์— ํ•ด๋‹น ๊ฐ’์„ ์„ธํŒ…ํ•œ๋‹ค.
  • ๊ฐ์ฒด์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ”„๋กœํผํ‹ฐ๋ผ๋ฉด [[Put]] ์•Œ๊ณ ๋ฆฌ์ฆ˜์€ ํ›จ์”ฌ ๋” ๋ฏธ๋ฌ˜ํ•˜๊ณ  ๋ณต์žกํ•ด์ง„๋‹ค.

3.3.9 ๊ฒŒํ„ฐ์™€ ์„ธํ„ฐ

  • [[Put]]๊ณผ [[Get]] ๊ธฐ๋ณธ ์—ฐ์‚ฐ์€ ์ด๋ฏธ ์กด์žฌํ•˜๊ฑฐ๋‚˜ ์ „ํ˜€ ์ƒˆ๋กœ์šด ํ”„๋กœํผํ‹ฐ์— ๊ฐ’์„ ์„ธํŒ…ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์กด ํ”„๋กœํผํ‹ฐ๋กœ๋ถ€ํ„ฐ ๊ฐ’์„ ์กฐํšŒํ•˜๋Š” ์—ญํ• ์„ ๊ฐ๊ฐ ๋‹ด๋‹นํ•œ๋‹ค.
  • ES5๋ถ€ํ„ฐ๋Š” ๊ฒŒํ„ฐ/์„ธํ„ฐ๋ฅผ ํ†ตํ•ด (๊ฐ์ฒด ์ˆ˜์ค€์ด ์•„๋‹Œ) ํ”„๋กœํผํ‹ฐ ์ˆ˜์ค€์—์„œ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ ๋กœ์ง์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฒŒํ„ฐ/์„ธํ„ฐ๋Š” ๊ฐ๊ฐ ์‹ค์ œ๋กœ ๊ฐ’์„ ๊ฐ€์ ธ์˜ค๋Š”/์„ธํŒ…ํ•˜๋Š” ๊ฐ์ถฐ์ง„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋‹ค.
  • ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฒŒํ„ฐ ๋˜๋Š” ์„ธํ„ฐ ์–ด๋Š ํ•œ์ชฝ์ด๊ฑฐ๋‚˜ ๋™์‹œ์— ๊ฒŒํ„ฐ/์„ธํ„ฐ๊ฐ€ ๋  ์ˆ˜ ์žˆ๊ฒŒ ์ •์˜ํ•œ ๊ฒƒ์„(โ€˜๋ฐ์ดํ„ฐ ์„œ์ˆ ์žโ€™์˜ ๋ฐ˜๋Œ€๋ง๋กœ) โ€˜์ ‘๊ทผ ์„œ์ˆ ์žAccessor Descriptionโ€˜๋ผ๊ณ  ํ•œ๋‹ค. ์ ‘๊ทผ ์„œ์ˆ ์ž์—์„œ๋Š” ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’๊ณผ writable ์†์„ฑ์€ ๋ฌด์‹œ๋˜๋ฉฐ ๋Œ€์‹  (configurable, enumerable๊ณผ ๋”๋ถˆ์–ด) ํ”„๋กœํผํ‹ฐ์˜ ๊ฒŸGet/์…‹Set ์†์„ฑ์ด ์ค‘์š”ํ•˜๋‹ค.
var myObject = {
    // 'a'์˜ ๊ฒŒํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.
    get a() {
        return 2;
    }
};
Object.defineProperty(
    myObject, // ํƒ€๊นƒ
    "b", // ํ”„๋กœํผํ‹ฐ๋ช…
    { // ์„œ์ˆ ์ž
        // 'b'์˜ ๊ฒŒํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.
        get: function(){ return this.a * 2 },
        // 'b'๊ฐ€ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋กœ ํ™•์‹คํžˆ ํ‘œ์‹œ๋˜๊ฒŒ ํ•œ๋‹ค.
        enumerable: true
    }
);
myObject.a; // 2
myObject.b; // 4
  • get a() {} ์ฒ˜๋Ÿผ ๋ฆฌํ„ฐ๋Ÿด ๊ตฌ๋ฌธ์œผ๋กœ ๊ธฐ์ˆ ํ•˜๋“ , defineProperty()๋กœ ๋ช…์‹œ์  ์ •์˜๋ฅผ ๋‚ด๋ฆฌ๋“  ์‹ค์ œ๋กœ ๊ฐ’์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์€ ๊ฐ์ฒด์— ํ”„๋กœํผํ‹ฐ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ๊ฑด ๊ฐ™์ง€๋งŒ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๋ฉด ์ž๋™์œผ๋กœ ๊ฒŒํ„ฐ ํ•จ์ˆ˜๋ฅผ ์€๋ฐ€ํ•˜๊ฒŒ ํ˜ธ์ถœํ•˜์—ฌ ์–ด๋–ค ๊ฐ’์ด๋ผ๋„ ๊ฒŒํ„ฐ ํ•จ์ˆ˜๊ฐ€ ๋ฐ˜ํ™˜ํ•œ ๊ฐ’์ด ๊ฒฐ๊ด๊ฐ’์ด ๋œ๋‹ค.
var myObject = {
    // 'a'์˜ ๊ฒŒํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.
    get a() {
        return 2;
    }
};
myObject.a = 3;
myObject.a; // 2
  • a์˜ ๊ฒŒํ„ฐ๊ฐ€ ์ •์˜๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ํ• ๋‹น๋ฌธ์œผ๋กœ ๊ฐ’์„ ์„ธํŒ…ํ•˜๋ ค๊ณ  ํ•˜๋ฉด ์—๋Ÿฌ ์—†์ด ์กฐ์šฉํžˆ ๋ฌด์‹œ๋œ๋‹ค. ์„ธํ‹ฐ๊ฐ€ ์žˆ์–ด๋„ ์ปค์Šคํ…€Custom ๊ฒŒํ„ฐ๊ฐ€ 2๋งŒ ๋ฐ˜ํ™˜ํ•˜๊ฒŒ ํ•˜๋“œ ์ฝ”๋”ฉ๋˜์–ด ์žˆ์–ด์„œ ์„ธํŒ…์€ ์žˆ์œผ๋‚˜ ๋งˆ๋‚˜๋‹ค.
  • ํ”„๋กœํผํ‹ฐ ๋‹จ์œ„๋กœ ๊ธฐ๋ณธ [[Put]] ์—ฐ์‚ฐ(ํ• ๋‹น)์„ ์˜ค๋ฒ„๋ผ์ด๋“œํ•˜๋Š” ์„ธํ„ฐ๊ฐ€ ์ •์˜๋˜์–ด์•ผ ํ•œ๋‹ค. ๊ฒŒํ„ฐ์™€ ์„ธํ„ฐ๋Š” ํ•ญ์ƒ ๋‘˜ ๋‹ค ์„ ์–ธํ•˜๋Š” ๊ฒƒ์ด ์ข‹๋‹ค(ํ•œ์ชฝ๋งŒ ์„ ์–ธํ•˜๋ฉด ์˜ˆ์ƒ์™ธ์˜ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ฌ ์ˆ˜ ์žˆ๋‹ค.
var myObject = {
    // 'a'์˜ ๊ฒŒํ„ฐ๋ฅผ ์ •์˜ํ•œ๋‹ค.
    get a() {
        return this._a_;
    },
    set a(val) {
        this._a_ = val * 2;
    }
};
myObject.a = 2;
myObject.a; // 4
  • ์˜ˆ์ œ์—์„œ ์ฃผ์–ด์ง„ ๊ฐ’ 2๋Š” ์‹ค์ œ๋กœ ๋‹ค๋ฅธ ๋ณ€์ˆ˜ _a_์— ํ• ๋‹น([[Put]]์—ฐ์‚ฐ)ํ•œ๋‹ค. _a_๋ผ๋Š” ๋ช…์นญ์€ ์ˆœ์ „ํžˆ ๊ด€๋ก€์ƒ ๋ถ™์ธ ๊ฒƒ์ด๊ณ  ๋กœ์ง๊ณผ๋Š” ์ „ํ˜€ ๋ฌด๊ด€ํ•œ ์ผ๋ฐ˜ ํ”„๋กœํผํ‹ฐ๋‹ค.

3.3.10 ์กด์žฌ ํ™•์ธ

  • ๊ฐ์ฒด์— ์–ด๋–ค ํ”„๋กœํผํ‹ฐ๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€๋Š” ๊ตณ์ด ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์–ป์ง€ ์•Š๊ณ ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
var myObject = {
    a: 2
};
("a" in myObject); // true
("b" in myObject); // false

myObject.hasOwnProperty( "a" ); // true
myObject.hasOwnProperty( "b" ); // false
  • in ์—ฐ์‚ฐ์ž๋Š” ์–ด๋–ค ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด์— ์กด์žฌํ•˜๋Š”์ง€ ์•„๋‹ˆ๋ฉด ์ด ๊ฐ์ฒด์˜ [[Prototype]] ์—ฐ์‡„๋ฅผ ๋”ฐ๋ผ๊ฐ”์„ ๋•Œ ์ƒ์œ„ ๋‹จ๊ณ„์— ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ์ด์™€ ๋‹ฌ๋ฆฌ hasOwnProperty()๋Š” ๋‹จ์ง€ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๊ฐ์ฒด์— ์žˆ๋Š”์ง€๋งŒ ํ™•์ธํ•˜๊ณ  [[Prototype]] ์—ฐ์‡„๋Š” ์ฐพ์ง€ ์•Š๋Š”๋‹ค.
  • ๊ฑฐ์˜ ๋ชจ๋“  ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” Object.prototype ์œ„์ž„์„ ํ†ตํ•ด hasOwnProperty()์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๊ฐ„ํ˜น (Object.create(null)) Object.prototype๊ณผ ์—ฐ๊ฒฐ๋˜์ง€ ์•Š์€ ๊ฐ์ฒด๋Š” myObject.hasOwnProperty() ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค.
  • ์ด๋Ÿด ๊ฒฝ์šฐ์—” Object.prototype.hasOwnProperty.call(myObject, โ€œaโ€) ์ฒ˜๋Ÿผ ๊ธฐ๋ณธ hasOwnProperty() ๋ฉ”์„œ๋“œ๋ฅผ ๋นŒ๋ ค์™€ myObject์— ๋Œ€ํ•ด ๋ช…์‹œ์ ์œผ๋กœ ๋ฐ”์ธ๋”ฉํ•˜๋ฉด ์ข€ ๋” ํ™•์‹คํ•˜๊ฒŒ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์—ด๊ฑฐ

  • ํ”„๋กœํผํ‹ฐ ์„œ์ˆ ์ž ์†์„ฑ ์ค‘ ํ•˜๋‚˜์ธ enumerable์˜ โ€˜์—ด๊ฑฐ ๊ฐ€๋Šฅ์„ฑโ€™ ๊ฐœ๋…์œผ๋กœ ์ข€ ๋” ์ž์„ธํžˆ ์‚ดํŽด๋ณด์ž.
var = myObject = {};
Object.defineProperty(
    myObject,
    "a",
    // 'a'๋ฅผ ์—ด๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ธํŒ…ํ•œ๋‹ค(๊ธฐ๋ณธ๊ฐ’)
    { enumerable: true, value: 2 }
);
Object.defineProperty(
    myObject,
    "b",
    // 'b'๋ฅผ ์—ด๊ฑฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ธํŒ…ํ•œ๋‹ค.
    { enumerable: false, value: 3 }
);
myObject.b; // 3
("b" in myObject); // true
myObject.hasOwnProperty( "b" ); // true
// ...
for (var k in myObject) {
    console.log( k, myObject[k] );
}
// "a" 2
  • myObject.b๋Š” ์‹ค์ œ ์กด์žฌํ•˜๋Š” ํ”„๋กœํผํ‹ฐ๋กœ ๊ทธ ๊ฐ’์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, forโ€ฆin ๋ฃจํ”„์—์„œ๋Š” ์ž์ทจ๋ฅผ ๊ฐ์ถฐ๋ฒ„๋ฆฐ๋‹ค. ์ด์ฒ˜๋Ÿผ โ€˜์—ด๊ฑฐ ๊ฐ€๋ŠฅEnumerableโ€™ ํ•˜๋‹ค๋Š” ๊ฑด ๊ธฐ๋ณธ์ ์œผ๋กœ โ€˜๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ ์ˆœํšŒ ๋ฆฌ์ŠคํŠธ์— ํฌํ•จโ€™๋œ๋‹ค๋Š” ๋œป์ด๋‹ค.
  • ํ”„๋กœํผํ‹ฐ๊ฐ€ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ์ง€๋Š” ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์œผ๋กœ๋„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
var = myObject = {};
Object.defineProperty(
    myObject,
    "a",
    // 'a'๋ฅผ ์—ด๊ฑฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ธํŒ…ํ•œ๋‹ค(๊ธฐ๋ณธ๊ฐ’)
    { enumerable: true, value: 2 }
);
Object.defineProperty(
    myObject,
    "b",
    // 'b'๋ฅผ ์—ด๊ฑฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ์„ธํŒ…ํ•œ๋‹ค.
    { enumerable: false, value: 3 }
);
myObject.propertyIsEnumerable( "a" ); // true
myObject.propertyIsEnumerable( "b" ); // false

Object.key( myObject ); // ["a"]
Object.getOwnPropertyNames( myObject ); // ["a", "b"]
  • propertyIsEnumerable()์€ ์–ด๋–ค ํ”„๋กœํผํ‹ฐ๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ง์† ํ”„๋กœํผํ‹ฐ์ธ ๋™์‹œ์— enumerable:true์ธ์ง€ ๊ฒ€์‚ฌํ•œ๋‹ค. Object.key()๋Š” Object.getOwnPropertyNames()์˜ ์—ด๊ฑฐ ๊ฐ€๋Šฅ ์—ฌ๋ถ€์™€ ์ƒ๊ด€์—†์ด ๊ฐ์ฒด์— ์žˆ๋Š” ๋ชจ๋“  ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • in๊ณผ hasOwnProprerty()๊ฐ€ [[Prototype]] ์—ฐ์‡„์˜ ํ™•์ธ์— ๋”ฐ๋ผ ์ฐจ์ด๊ฐ€ ์žˆ๋Š” ๋ฐ˜๋ฉด, Object.keys()์™€ Object.getOwnProertyNames()๋Š” ๋ชจ๋‘ ์ฃผ์–ด์ง„ ๊ฐ์ฒด๋งŒ ํ™•์ธํ•œ๋‹ค.
  • in ์—ฐ์‚ฐ์ž์™€ ๊ฒฐ๊ณผ๊ฐ€ ๋™๋“ฑํ•œ ํ”„๋กœํผํ‹ฐ ์ „์ฒด ๋ฆฌ์ŠคํŠธ๋ฅผ ์กฐํšŒํ•˜๋Š” ๊ธฐ๋Šฅ์€ (์ง€๊ธˆ์€) ์—†๋‹ค. ๋‹จ๊ณ„๋งˆ๋‹ค Object.keys()์—์„œ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ํฌ์ฐฉํ•˜์—ฌ ์žฌ๊ท€์ ์œผ๋กœ ์ฃผ์–ด์ง„ ๊ฐ์ฒด์˜ [[Property]] ์—ฐ์‡„๋ฅผ ์ˆœํšŒํ•˜๋Š” ์‹์˜ ๋กœ์ง์„ ๊ตฌํ˜„ํ•˜์—ฌ ๋Œ€๋žต ๋น„์Šทํ•œ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ๋งŒ๋“ค์–ด ์“ฐ๋ฉด ๋œ๋‹ค.

3.4 ์ˆœํšŒ

  • forโ€ฆin ๋ฃจํ”„๋Š” ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ๋ฅผ ([[Prototype]] ์—ฐ์‡„๋„ ํฌํ•จํ•˜์—ฌ) ์ฐจ๋ก€๋กœ ์ˆœํšŒํ•œ๋‹ค.
  • ํ”„๋กœํผํ‹ฐ ๊ฐ’์„ ์ˆœํšŒํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ํ• ๊นŒ? ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ๋ณด์ž.
var myArray = [1,2,3];
for (var i = 0; i < myArray.length; i ++) {
    console.log( myArray[i] );
}
// 1 2 3
  • ์ด ์ฝ”๋“œ๋Š” ์ธ๋ฑ์Šค๋ฅผ ์ˆœํšŒํ•˜๋ฉด์„œ ํ•ด๋‹น ๊ฐ’(myArray[i])์„ ์‚ฌ์šฉํ•  ๋ฟ ๊ฐ’ ์ž์ฒด๋ฅผ ์ˆœํšŒํ•˜๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.
  • ES5๋ถ€ํ„ฐ๋Š” forEach(), every(), some() ๋“ฑ์˜ ๋ฐฐ์—ด ๊ด€๋ จ ์ˆœํšŒ ํ—ฌํผ๊ฐ€ ๋„์ž…๋๋‹ค. ์ด ํ•จ์ˆ˜๋“ค์€ ๋ฐฐ์—ด์˜ ๊ฐ ์›์†Œ์— ์ ์šฉํ•  ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋ฅผ ์ธ์ž๋กœ ๋ฐ›์œผ๋ฉฐ, ์›์†Œ๋ณ„๋กœ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง๋งŒ ๋‹ค๋ฅด๋‹ค.
  • forEach()๋Š” ๋ฐฐ์—ด ์ „์ฒด ๊ฐ’์„ ์ˆœํšŒํ•˜์ง€๋งŒ ์ฝœ๋ฐฑ ํ•จ์ˆ˜์˜ ๋ฐ˜ํ™˜ ๊ฐ’์€ ๋ฌด์‹œํ•œ๋‹ค.
  • every()๋Š” ๋ฐฐ์—ด ๋๊นŒ์ง€ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ false(๋˜๋Š” โ€˜falsyโ€™๊ฐ’)๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€ ์ˆœํšŒํ•˜๋ฉฐ some()์€ ์ด์™€ ์ •๋ฐ˜๋Œ€๋กœ ๋ฐฐ์—ด ๋๊นŒ์ง€ ๋˜๋Š” ์ฝœ๋ฐฑ ํ•จ์ˆ˜๊ฐ€ true(๋˜๋Š” โ€˜truthyโ€™๊ฐ’)๋ฅผ ๋ฐ˜ํ™˜ํ•  ๋•Œ๊นŒ์ง€ ์ˆœํšŒํ•œ๋‹ค. every()์™€ some()์˜ ์ด๋Ÿฌํ•œ ํŠน๋ณ„ํ•œ ๋ฐ˜ํ™˜ ๊ฐ’์€ ์ผ๋ฐ˜์ ์ธ for ๋ฃจํ”„์˜ break๋ฌธ์ฒ˜๋Ÿผ ๋๊นŒ์ง€ ์ˆœํšŒํ•˜๊ธฐ ์ „์— ์ผ์ฐŒ๊ฐ์น˜ ์ˆœํšŒ๋ฅผ ๋๋‚ด๋Š” ๋ฐ ์“ฐ์ธ๋‹ค.
  • forโ€ฆin ๋ฃจํ”„๋ฅผ ์ด์šฉํ•œ ๊ฐ์ฒด ์ˆœํšŒ๋Š” ์‹ค์ œ๋กœ ์—ด๊ฑฐ ๊ฐ€๋Šฅํ•œ ํ”„๋กœํผํ‹ฐ๋งŒ ์ˆœํšŒํ•˜๊ณ  ๊ทธ ๊ฐ’์„ ์–ป์œผ๋ ค๋ฉด ์ผ์ผ์ด ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•ด์•ผ ํ•˜๋ฏ€๋กœ ๊ฐ„์ ‘์ ์ธ ๊ฐ’ ์ถ”์ถœ์ด๋‹ค.
  • ๋ฐฐ์—ด ์ธ๋ฑ์Šค(๋‚˜ ๊ฐ์ฒด ํ”„๋กœํผํ‹ฐ)๊ฐ€ ์•„๋‹Œ ๊ฐ’์„ ์ง์ ‘ ์ˆœํšŒํ•˜๊ธฐ ์œ„ํ•ด ES6๋ถ€ํ„ฐ ๋ฐฐ์—ด(์ž์ฒด ์ปค์Šคํ…€ ์ˆœํšŒ์ž๊ฐ€ ์ •์˜๋œ ๊ฐ์ฒด) ์ˆœํšŒ์šฉ forโ€ฆof ๊ตฌ๋ฌธ์„ ์ œ๊ณตํ•œ๋‹ค.
var myArray = [ 1,2,3 ];
for (var v of myArray) {
    console.log( v );
}
// 1
// 2
// 3
  • forโ€ฆof ๋ฃจํ”„๋Š” ์ˆœํšŒํ•  ์›์†Œ์˜ ์ˆœํšŒ์ž ๊ฐ์ฒดIterator Object(๋ช…์„ธ์‹์œผ๋กœ ๋งํ•˜๋ฉด @@iterator๋ผ๋Š” ๊ธฐ๋ณธ ๋‚ด๋ถ€ ํ•จ์ˆ˜)๊ฐ€ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์ˆœํšŒ๋‹น ํ•œ ๋ฒˆ์”ฉ ์ด ์ˆœํšŒ์ž ๊ฐ์ฒด์˜ next() ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ์—ฐ์†์ ์œผ๋กœ ๋ฐ˜ํ™˜ ๊ฐ’์„ ์ˆœํšŒํ•œ๋‹ค.
  • ๋ฐฐ์—ด์€ @@iterator๊ฐ€ ๋‚ด์žฅ๋œ ๋•๋ถ„์— ๋‹ค์Œ ์˜ˆ์ œ์—์„œ ๋ณด๋‹ค์‹œํ”ผ ์†์‰ฝ๊ฒŒ forโ€ฆof ๋ฃจํ”„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚ด์žฅ @@iterator๋ฅผ ์ด์šฉํ•˜์—ฌ ์ˆ˜๋™์œผ๋กœ ๋ฐฐ์—ด์„ ์ˆœํšŒํ•˜๋ฉด์„œ ์ž‘๋™ ์›๋ฆฌ๋ฅผ ์‚ดํŽด๋ณด์ž.
var myArray = [ 1,2,3 ]l
var it = myArray[Symbol.iterator]();

it.next(); // { value:1, done:false }
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { done:true }
  • ์ˆœํšŒ์ž์˜ next()๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒฐ๊ด๊ฐ’์€ { value: , done: } ํ˜•ํƒœ์˜ ๊ฐ์ฒด๋กœ, ์—ฌ๊ธฐ์„œ value๋Š” ํ˜„์žฌ ์ˆœํšŒ ๊ฐ’, done์€ ๋‹ค์Œ์— ์ˆœํšŒํ•  ๊ฐ’์˜ ์œ ๋ฌด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ถˆ๋ฆฌ์–ธ ๊ฐ’์ด๋‹ค.
  • 3์ด ๋ฐ˜ํ™˜๋๋Š”๋ฐ๋„ done: false์ธ ๊ฒƒ์€ ES6 ์ œ๋„ˆ๋ ˆ์ดํ„ฐGeneratorํ•จ์ˆ˜์˜ ์˜๋ฏธ ๋•Œ๋ฌธ์ด๋‹ค.
  • ๋ฐฐ์—ด์€ forโ€ฆof ๋ฃจํ”„ ๋‚ด์—์„œ ์•Œ์•„์„œ ์ˆœํšŒํ•˜์ง€๋งŒ, ์ผ๋ฐ˜ ๊ฐ์ฒด๋Š” ๋‚ด๋ถ€์— @@iterator๊ฐ€ ์—†๋‹ค. ES6์—์„œ @@iterator๋ฅผ ์˜๋„์ ์œผ๋กœ ๋ˆ„๋ฝ์‹œํ‚จ ์ด์œ ๋Š” ์•ž์œผ๋กœ ๋“ฑ์žฅํ•  ์ƒˆ๋กœ์šด ํƒ€์ž…์˜ ๊ฐ์ฒด์—์„œ ๋ฌธ์ œ์˜ ์†Œ์ง€๊ฐ€ ๋  ์ˆ˜ ์žˆ๋‚˜๋Š” ์ ์„ ์ƒ๊ฐํ•ด๋ณด๋ฉด ์ฐจ๋ผ๋ฆฌ ๋‹คํ–‰์Šค๋Ÿฌ์šด ์ผ์ธ ๊ฒƒ ๊ฐ™๋‹ค.
  • ์ˆœํšŒํ•˜๋ ค๋Š” ๊ฐ์ฒด์˜ ๊ธฐ๋ณธ @@iterator๋ฅผ ์†์ˆ˜ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ๋‹ค์Œ ์˜ˆ์ œ๋ฅผ ๋ณด์ž.
var myObject = {
    a: 2,
    b: 3
};
Object.definePropery( myObject, Symbol.iterator, {
   enumerable: false,
   writable: false,
   configurable: true,
   value: function() {
        var o = this;
        var idx = 0;
        var ks = Object.keys( o );
        return {
            next: function() {
                return {
                    return {
                        value: o[ks[idx++]],
                        done: (idx > ks.length)
                    }
                };
            }
        };
   }
});
// myObject๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ˆœํšŒํ•œ๋‹ค.
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { value:undefined, done:false }

// myObject๋ฅผ 'for...of' ๋ฃจํ”„๋กœ ์ˆœํšŒํ•œ๋‹ค.
for (var v of myObject) {
    console.log( v );
}
// 2
// 3
  • ์˜ˆ์ œ ์ฝ”๋“œ์—์„  ๋‹จ์ˆœํžˆ ๊ฐ’ ๋Œ€ ๊ฐ’์œผ๋กœ ์ˆœํšŒํ•˜๊ณ  ์žˆ์ง€๋งŒ ํ•„์š”์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ž ์ž๋ฃŒ ๊ตฌ์กฐ์— ๋”ฑ ๋งž๋Š” ์ž„์˜์˜ ๋ณต์žกํ•œ ์ˆœํšŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ •์˜ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ES6์˜ forโ€ฆof ๋ฃจํ”„์™€ ์ปค์Šคํ…€ ์ˆœํšŒ์ž๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๊ฐ์ฒด๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๋ฐ ์•„์ฃผ ํƒ์›”ํ•œ ์ƒˆ๋กœ์šด ๊ตฌ๋ฌธ ๋„๊ตฌSyntactic Tool๋‹ค.

3.5 ์ •๋ฆฌํ•˜๊ธฐ