Chapter 3: Objects - hochan222/Everything-in-JavaScript GitHub Wiki

Chapter 3: Objects

this ๋ฐ”์ธ๋”ฉ์—์„œ ๊ทธ ์ค‘์‹ฌ์—” ๊ฐ์ฒด๊ฐ€ ์žˆ์—ˆ๋‹ค. ๊ฐ์ฒด๋ž€ ๋ฌด์—‡์ธ๊ฐ€ ์•Œ์•„๋ณด์ž.

Syntax

๊ฐ์ฒด๋Š” ๋‘๊ฐ€์ง€ ํ˜•ํƒœ๋กœ ์ œ๊ณต๋œ๋‹ค. (๋ฆฌํ„ฐ๋Ÿด, ์ƒ์„ฑ๋œ ํผ)

literal syntax

var myObj = {
	key: value
	// ...
};

constructed form

var myObj = new Object();
myObj.key = value;

๋‘ ๊ฐ€์ง€ ๋ฐฉ์‹์€ ํ™•์‹คํ•˜๊ฒŒ ๋™์ผํ•œ ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•œ๋‹ค. ์œ ์ผํ•œ ์ฐจ์ด์ ์€ ๋ฆฌํ„ฐ๋Ÿด์€ ์ดˆ๊ธฐํ™”์‹œ ํ‚ค, ๊ฐ’์œผ๋กœ ํ•œ๋ฒˆ์— ํ•ด์ค„ ์ˆ˜ ์žˆ์ง€๋งŒ constructed form์€ ํ•˜๋‚˜ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

Type

๊ฐ์ฒด๋Š” JS์—์„œ 6๊ฐ€์ง€ primitive value์ค‘ ํ•˜๋‚˜๋‹ค.

  • string
  • number
  • boolean
  • null
  • undefined
  • object

primitive value๋Š” ๊ทธ ์ž์ฒด๊ฐ€ object๋Š” ์•„๋‹ˆ๋‹ค. null๊ฐ™์€ ๊ฒฝ์šฐ ์–ธ์–ด์  ์‹ค์ˆ˜๋กœ typeof๋ฅผ ์ถœ๋ ฅํ•˜๋ฉด object๊ฐ€ ๋‚˜์˜ค์ง€๋งŒ ๊ฐ์ฒด๋Š” ์•„๋‹ˆ๋‹ค.

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“ ๊ฒƒ์€ ๊ฐ์ฒด๋ผ๋Š” ๋ง์€ ์ž˜๋ชป๋œ ์„œ์ˆ ์ด๋‹ค.

๋ฐ˜๋ฉด, complex primitives๋ผ๊ณ  ๋ถˆ๋ผ๋Š” sub-type ๊ฐ์ฒด๋“ค์ด ์žˆ๋‹ค.

ํ•จ์ˆ˜๋Š” ๊ฐ์ฒด์˜ ํ•˜์œ„ ์œ ํ˜•์ด๋‹ค. ("callable object") ํ•จ์ˆ˜๋Š” ํ˜ธ์ถœ ๊ฐ€๋Šฅํ•œ ๋™์ž‘์ด ์—ฐ๊ฒฐ๋์„ ๋ฟ ์ผ๋ฐ˜ ๊ฐ์ฒด์ผ ๋ฟ์ด๋ฏ€๋กœ "first class"๋ผ๊ณ  ํ•œ๋‹ค.

๋ฐฐ์—ด ์—ญ์‹œ ์ถ”๊ฐ€ ๋™์ž‘์ด์žˆ๋Š” ๊ฐ์ฒด์ด๋‹ค. ๋ฐฐ์—ด์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ๋Š” ๊ฐ์ฒด๋ณด๋‹ค ์•ฝ๊ฐ„ ๋” ๊ตฌ์กฐํ™” ๋ผ์žˆ๋‹ค.

Built-in Objects

์ผ๋ฐ˜์ ์œผ๋กœ ๋‚ด์žฅ ๊ฐ์ฒด๋ผ๊ณ  ํ•˜๋Š” object sub-types๋“ค์ด ์žˆ๋‹ค.

  • String
  • Number
  • Boolean
  • Object
  • Function
  • Array
  • Date
  • RegExp
  • Error

๋‹ค๋ฅธ ์–ธ์–ด๋กœ ๋ฏธ๋ค„๋ดค์„ ๋•Œ ์ด๊ฒƒ๋“ค์€ ์˜ˆ๋ฅผ๋“ค์–ด String class๋กœ ๋ณด์ผ ์ˆ˜ ์žˆ์ง€๋งŒ JS์—์„œ๋Š” ๊ทธ๋ƒฅ ํ•จ์ˆ˜์ผ ๋ฟ์ด๋‹ค.

var strPrimitive = "I am a string";
typeof strPrimitive;			        // "string"
strPrimitive instanceof String;		        // false

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

// inspect the object sub-type
Object.prototype.toString.call( strObject );	// [object String]

strPrimitive๋Š” ๊ฐ์ฒด๊ฐ€ ์•„๋‹ˆ๊ณ  ๊ธฐ๋ณธ ๋ฆฌํ„ฐ๋Ÿด์ด๋‹ค.
๊ธธ์ด ํ™•์ธ, ๊ฐœ๋ณ„ ๋ฌธ์ž ์ ‘๊ทผ๋“ฑ๊ณผ ๊ฐ™์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜๋ ค๋ฉด String ๊ฐ์ฒด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

์šด์ข‹๊ฒŒ๋„ JS๋Š” string primitive value๋ฅผ String ๊ฐ์ฒด๋กœ ๊ฐ•์ œ ํ˜•๋ณ€ํ™˜์„ ์‹œ์ผœ์ค€๋‹ค. JS ์ปค๋ฎค๋‹ˆํ‹ฐ์—์„œ๋„ String ๊ฐ์ฒด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ๋ฆฌํ„ฐ๋Ÿด์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒƒ์„ ๊ฐ•๋ ฅํ•˜๊ฒŒ ์ถ”์ฒœํ•œ๋‹ค.

var strPrimitive = "I am a string";

console.log( strPrimitive.length );		// 13
console.log( strPrimitive.charAt( 3 ) );	// "m"

์—”์ง„์ด ์ž๋™์œผ๋กœ ํ˜•๋ณ€ํ™˜ ํ•ด์ค€๋‹ค!

42.359.toFixed(2)๋„ ๊ฐ™์€ ๊ฒฝ์šฐ์ด๋ฉฐ Boolean๋„ ๋งˆ์ฐฌ๊ฐ€์ง€์ด๋‹ค.

null, undefined๋Š” ๊ฐ์ฒด ๋ž˜ํผ๋Š” ์—†๊ณ  ๊ธฐ๋ณธ ๊ฐ’๋งŒ ์žˆ๋‹ค. ๋ฐ˜๋ฉด์—, ๋‚ ์งœ ํผ์€ ๋ฆฌํ„ฐ๋Ÿด์ด ์—†์œผ๋ฏ€๋กœ ๊ฐ์ฒด ํ˜•์‹์œผ๋กœ๋งŒ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

Object, Array, Function, RegExp๋Š” ๋ชจ๋‘ ์‚ฌ์šฉ ํ˜•์‹๊ณผ๋Š” ๊ด€๋ จ์—†์ด ๋ชจ๋‘ ๊ฐ์ฒด์ด๋‹ค.

Contents

๊ฐ์ฒด์˜ ๊ฐ’๋“ค์€ properties๋ผ ๋ถ€๋ฅด๋Š” locations์— ์ €์žฅ์ด๋œ๋‹ค.

์—”์ง„ ๊ตฌํ˜„๋งˆ๋‹ค ๋‹ค ๋‹ค๋ฅผ์ˆ˜ ์žˆ์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์ปจํ…Œ์ด๋„ˆ์— ์ €์žฅ๋˜๋Š” ๊ฒƒ๋“ค์€ ๊ฐ์ฒด ์ €์žฅ ์œ„์น˜์˜ ํฌ์ธํ„ฐ๋“ค์ธ property ์ด๋ฆ„๋“ค์ด๋‹ค.

var myObject = {
	a: 2
};

myObject.a;		// 2

myObject["a"];	// 2

myObject์—์„œ location a์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ., [] ์—ฐ์‚ฐ์ž๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. .a๋ฌธ๋ฒ•์€ ํ”ํžˆ ํ”„๋กœํผํ‹ฐ์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๊ณ , ```["a"]๋ฌธ๋ฒ•์€ "key"์— ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค. ์‚ฌ์‹ค ๋‘˜๋‹ค ๋™์ผํ•˜๋‹ค.

var wantA = true;
var myObject = {
	a: 2
};

var idx;

if (wantA) {
	idx = "a";
}

// later

console.log( myObject[idx] ); // 2

๊ฐ์ฒด์—์„œ ์†์„ฑ์˜ ์ด๋ฆ„์€ ํ•ญ์ƒ ๋ฌธ์ž์—ด์ด๋‹ค. ๋งŒ์•ฝ ๋‹ค๋ฅธ ๊ฐ’์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋œ๋‹ค.

var myObject = { };

myObject[true] = "foo";
myObject[3] = "bar";
myObject[myObject] = "baz";

myObject["true"];		// "foo"
myObject["3"];			// "bar"
myObject["[object Object]"];	// "baz"

Computed Property Names

๋‹ค์Œ๊ณผ ๊ฐ™์€ ํ‘œํ˜„๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

var prefix = "foo";

var myObject = {
	[prefix + "bar"]: "hello",
	[prefix + "baz"]: "world"
};

myObject["foobar"]; // hello
myObject["foobaz"]; // world

computed property names์˜ ๋ณดํ†ต ์‚ฌ์šฉ์ฒ˜๋Š” ES6์˜ Symbol์ธ๋ฐ ์—”์ง„๋งˆ๋‹ค Symbol์˜ ๊ฐ’์ด ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๊ฒƒ์€ ๊ธฐ์ˆ ์ ์œผ๋กœ๋Š” ๋ฌธ์ž์—ด์ธ ์ถ”์ธกํ• ์ˆ˜ ์—†๋Š” ๊ฐ’์„ ๊ฐ–๋Š” primitive value์ด๋‹ค.

var myObject = {
	[Symbol.Something]: "hello world"
};

Property vs. Method

ํ”ํžˆ ๊ฐœ๋ฐœ์ž๋“ค์€ ์ด ๋‘˜์„ ๊ตฌ๋ถ„ํ•˜๊ธธ ์›ํ•œ๋‹ค. ํ•˜์ง€๋งŒ JS specification์€ ์ด ๋‘ ๋‹จ์–ด๋ฅผ ๋™์ผํ•˜๊ฒŒ ๋งŒ๋“ ๋‹ค.

function foo() {
	console.log( "foo" );
}

var someFoo = foo;	// variable reference to `foo`

var myObject = {
	someFoo: foo
};

foo;				// function foo(){..}

someFoo;			// function foo(){..}

myObject.someFoo;	// function foo(){..}
var myObject = {
	foo: function foo() {
		console.log( "foo" );
	}
};

var someFoo = myObject.foo;

someFoo;	// function foo(){..}

myObject.foo;	// function foo(){..}

Arrays

๋ฐฐ์—ด๋„ [] ์—ฐ์‚ฐ์ž๋กœ ์ ‘๊ทผ์„ ํ•˜๊ณ  ์กฐ๊ธˆ ๋” ๋ณต์žกํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ–๋Š”๋‹ค.

var myArray = [ "foo", 42, "bar" ];

myArray.length;		// 3

myArray[0];			// "foo"

myArray[2];			// "bar"
var myArray = [ "foo", 42, "bar" ];

myArray.baz = "baz";

myArray.length;	// 3

myArray.baz;	// "baz"

. ๋˜๋Š” [] ์—ฐ์‚ฐ์ž ๊ตฌ๋ฌธ์— ๊ด€๊ณ„์—†์ด ๋ช…๋ช…๋œ ์†์„ฑ์„ ์ถ”๊ฐ€ํ•ด๋„ ๋ฐฐ์—ด ๊ธธ์ด๋Š” ๋ณ€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
ํ•˜์ง€๋งŒ ๋ฐฐ์—ด์ด๋Š” ๋ฐฐ์—ด์„ ๋งŒ๋“  ์˜๋„์™€ ๊ฑฐ๋ฆฌ๊ฐ€ ๋ฉ€์–ด์„œ ์‚ฌ์šฉ์„ ์ž์ œํ•˜์ž.

var myArray = [ "foo", 42, "bar" ];

myArray["3"] = "baz";

myArray.length;	// 4

myArray[3];		// "baz"

Duplicating Objects

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์—์„œ ํ”ํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋Šฅ์€ ๋ณต์‚ฌ์ด๋‹ค. ํ•˜์ง€๋งŒ ๊ฐ์ฒด๋ฅผ ๋ณต์ œํ•˜๋Š”๊ฒƒ์€ ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์ด ๋ณต์žกํ•˜๋‹ค.

function anotherFunction() { /*..*/ }

var anotherObject = {
	c: true
};

var anotherArray = [];

var myObject = {
	a: 2,
	b: anotherObject,	// reference, not a copy!
	c: anotherArray,	// another reference!
	d: anotherFunction
};

anotherArray.push( anotherObject, myObject );

์šฐ์„  ๊นŠ์€๋ณต์‚ฌ์™€ ์–•์€ ๋ณต์‚ฌ์ค‘ ์–ด๋Š๊ฒƒ์— ํ•ด๋‹นํ•˜๋Š”์ง€ ๋‹ตํ•ด์•ผํ•œ๋‹ค. ๋ชจ๋‘ ์ฐธ์กฐ๊ฐ’์„ ๊ฐ–๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๊ฐ์ฒด๋Š” ์ˆœํ™˜ ์ฐธ์กฐ์˜ ์œ„ํ—˜์„ฑ์ด์žˆ๋‹ค.

๋ณต์ œ์—๋Œ€ํ•œ ํ‘œ์ค€์€ ์ •ํ•ด์ ธ์žˆ์ง€ ์•Š๊ณ , ๊ฐ JS ํ”„๋ ˆ์ž„์›Œํฌ๋“ค์€ ์•Œ์•„์„œ ์ž๊ธฐ๋“ค๋งŒ์˜ ๋ฐฉ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ๋‹ค. ํ•˜๋‚˜์˜ ์†”๋ฃจ์…˜์€ JSON์„ ์ด์šฉํ•˜๋Š”๊ฒƒ์ด๋‹ค.

var newObj = JSON.parse( JSON.stringify( someObj ) );

ES6๋Š” ์–•์€ ๋ณต์‚ฌ๋ฅผ Object.assign()์œผ๋กœ ์ •์˜ํ–ˆ๋‹ค.

var newObj = Object.assign( {}, myObject );

newObj.a;			// 2
newObj.b === anotherObject;	// true
newObj.c === anotherArray;	// true
newObj.d === anotherFunction;	// true

Property Descriptors

var myObject = {
	a: 2
};

Object.getOwnPropertyDescriptor( myObject, "a" );
// {
//    value: 2,
//    writable: true,
//    enumerable: true,
//    configurable: true
// }
var myObject = {};

Object.defineProperty( myObject, "a", {
	value: 2,
	writable: true,
	configurable: true,
	enumerable: true
} );

myObject.a; // 2

Writable

var myObject = {};

Object.defineProperty( myObject, "a", {
	value: 2,
	writable: false, // not writable!
	configurable: true,
	enumerable: true
} );

myObject.a = 3;

myObject.a; // 2

strict mode์—์„œ๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

"use strict";

var myObject = {};

Object.defineProperty( myObject, "a", {
	value: 2,
	writable: false, // not writable!
	configurable: true,
	enumerable: true
} );

myObject.a = 3; // TypeError

Configurable

var myObject = {
	a: 2
};

myObject.a = 3;
myObject.a;					// 3

Object.defineProperty( myObject, "a", {
	value: 4,
	writable: true,
	configurable: false,	// not configurable!
	enumerable: true
} );

myObject.a;					// 4
myObject.a = 5;
myObject.a;					// 5

Object.defineProperty( myObject, "a", {
	value: 6,
	writable: true,
	configurable: true,
	enumerable: true
} ); // TypeError

ํ•œ๋ฒˆ false๋ฉด true๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์—†๋‹ค.
๋˜ํ•œ configurable์€ ๊ฐ์ฒด๊ฐ€ delete ์—ฐ์‚ฐ์ž์— ์˜ํ•ด ์ œ๊ฑฐ๋˜๋Š”๊ฒƒ์„ ๋ฐฉ์ง€ํ•œ๋‹ค.

var myObject = {
	a: 2
};

myObject.a;				// 2
delete myObject.a;
myObject.a;				// undefined

Object.defineProperty( myObject, "a", {
	value: 2,
	writable: true,
	configurable: false,
	enumerable: true
} );

myObject.a;				// 2
delete myObject.a;
myObject.a;				// 2

delete๋Š” c,c++์—์„œ์ฒ˜๋Ÿผ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์—ญํ• ๋ณด๋‹ค๋Š” ๊ฐ์ฒด ์†์„ฑ์„ ์ œ๊ฑฐํ•˜๋Š” ์—ญํ• ๋กœ ์ƒ๊ฐํ•˜์ž.

Immutability

๊ฐ์ฒด์— ๋‹ค๋ฅธ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š”๊ฒฝ์šฐ ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋‚ด์šฉ์€ ์˜ํ–ฅ์„ ๋ฐ›์ง€์•Š๊ณ  ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ๋‹ค.

myImmutableObject.foo; // [1,2,3]
myImmutableObject.foo.push( 4 );
myImmutableObject.foo; // [1,2,3,4]

myImmutableObject๊ฐ€ ๋ถˆ๋ณ€์œผ๋กœ ๋ณดํ˜ธ๋˜์–ด๋„ myImmutableObject.foo๋Š” ๋ณ€ํ•  ์ˆ˜ ์žˆ๋‹ค.

Object Constant

writable : false ๋ฐ configurable : false๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ƒ์ˆ˜ ๊ฐ์ฒด ์†์„ฑ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

var myObject = {};

Object.defineProperty( myObject, "FAVORITE_NUMBER", {
	value: 42,
	writable: false,
	configurable: false
} );

Prevent Extensions

๊ฐ์ฒด์˜ ์ƒˆ ์†์„ฑ ์ถ”๊ฐ€๋ฅผ ์˜ˆ๋ฐฉํ•˜๊ณ  ์‹ถ์œผ๋ฉด Object.preventExtensions(..)์„ ์‚ฌ์šฉํ•˜์ž.

var myObject = {
	a: 2
};

Object.preventExtensions( myObject );

myObject.b = 3;
myObject.b; // undefined

strict mode์—์„œ๋Š” TypeError๊ฐ€ ๋œฌ๋‹ค.

Seal

Object.seal(..)์€ Object.preventExtensions(..)์™€ configurable:false์ด ์ ์šฉ๋œ๋‹ค.

Freeze

Object.seal(..)์— writable:false๊นŒ์ง€ ์ ์šฉ๋œ๋‹ค.

์ด๊ฒŒ ๊ฐ์ฒด์— ์ ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€์žฅ ๋†’์€ ์ˆ˜์ค€์˜ ๋ถˆ๋ณ€์„ฑ์ด๋‹ค.

[Get](/hochan222/Everything-in-JavaScript/wiki/Get)

var myObject = {
	a: 2
};

myObject.a; // 2

myObject.a๋Š” ์†์„ฑ ์•ก์„ธ์Šค์ด์ง€๋งŒ, ๋ณด์ด๋Š” ๊ฒƒ์ฒ˜๋Ÿผ myObject์—์„œ ์ด๋ฆ„ a์˜ ์†์„ฑ์„ ์ฐพ๋Š” ๊ฒƒ์€ ์•„๋‹ˆ๋‹ค.

์‚ฌ์–‘์— ๋”ฐ๋ฅด๋ฉด ์œ„์˜ ์ฝ”๋“œ๋Š” myObject์—์„œ Get ์—ฐ์‚ฐ (ํ•จ์ˆ˜ ํ˜ธ์ถœ๊ณผ ์œ ์‚ฌ ํ•จ : Get ())์„ ์‹ค์ œ๋กœ ์ˆ˜ํ–‰ํ•œ๋‹ค. ๊ฐ์ฒด์— ๋Œ€ํ•œ ๊ธฐ๋ณธ ๋‚ด์žฅ Get ์ž‘์—…์€ ๋จผ์ € ์š”์ฒญ ๋œ ์ด๋ฆ„์˜ ์†์„ฑ์— ๋Œ€ํ•ด ๊ฐ์ฒด๋ฅผ ๊ฒ€์‚ฌํ•˜๊ณ ,์ด๋ฅผ ์ฐพ์œผ๋ฉด ๊ทธ์— ๋”ฐ๋ผ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

Get ์ž‘์—…์˜ ์ค‘์š”ํ•œ ๊ฒฐ๊ณผ ์ค‘ ํ•˜๋‚˜๋Š” ์š”์ฒญ ๋œ ์†์„ฑ์— ๋Œ€ํ•œ ๊ฐ’์„ ์–ป์„ ์ˆ˜์—†๋Š” ๊ฒฝ์šฐ ๋Œ€์‹  undefined ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

var myObject = {
	a: 2
};

myObject.b; // undefined
var myObject = {
	a: undefined
};

myObject.a; // undefined
myObject.b; // undefined

Get ์ž‘์—…์€ ๋ฏธ๋ฌ˜ํ•˜์ง€๋งŒ ์ฐธ์กฐ myObject.a๋ณด๋‹ค ์ฐธ์กฐ myObject.b์— ๋Œ€ํ•ด ๋” ๋งŽ์€ ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

[Put](/hochan222/Everything-in-JavaScript/wiki/Put)

์†์„ฑ์—์„œ ๊ฐ’์„ ๊ฐ€์ ธ ์˜ค๊ธฐ ์œ„ํ•ด ๋‚ด๋ถ€์ ์œผ๋กœ ์ •์˜ ๋œ Get ์ž‘์—…์ด ์žˆ์œผ๋ฏ€๋กœ ๊ธฐ๋ณธ Put ์ž‘์—…๋„ ํ•„์—ฐ์ ์œผ๋กœ ์กด์žฌํ•œ๋‹ค.

๋‹ค์Œ์€ Put ์ž‘๋™ ๋ฐฉ์‹์ด๋‹ค.

  1. Property๊ฐ€ accessor descriptor์ธ์ง€?
  • ๋งŒ์•ฝ์— ๋งž์œผ๋ฉด the setter๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค.
  1. Property์˜ data descriptor์˜ writable์ด false๋กœ ์„ค์ •๋ผ์žˆ๋Š”์ง€?
  • non-strict mode์—์„œ๋Š” ์‹คํŒจํ•˜๊ณ , strict mode์—์„œ๋Š” TypeError๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  1. ๋‹ค์Œ ํ•ด๋‹น์‚ฌํ•ญ์— ์—†์œผ๋ฉด ์กด์žฌํ•˜๋Š” property์˜ ๊ฐ’์„ ์ •์ƒ์œผ๋กœ ์ €์žฅํ•œ๋‹ค.

Getters & Setters

ES5๋Š” getter ๋ฐ setter๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ด๋Ÿฌํ•œ ๊ธฐ๋ณธ ์ž‘์—…์˜ ์ผ๋ถ€๋ฅผ ๊ฐ์ฒด ์ˆ˜์ค€์ด ์•„๋‹ˆ๋ผ ์†์„ฑ ๋ณ„ ์ˆ˜์ค€์—์„œ ์žฌ์ •์˜ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋„์ž…ํ–ˆ๋‹ค. getter๋Š” ์‹ค์ œ๋กœ ์ˆจ๊ฒจ์ง„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜์—ฌ ๊ฐ’์„ ๊ฒ€์ƒ‰ํ•˜๋Š” ์†์„ฑ์ด๋‹ค. setter ์‹ค์ œ๋กœ ๊ฐ’์„ ์„ค์ •ํ•˜๊ธฐ ์œ„ํ•ด ์ˆจ๊ฒจ์ง„ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ์†์„ฑ์ด๋‹ค.

property์— getter, setter ๋‘˜๋‹ค ๊ฐ–๊ฒŒ ์„ค์ •ํ•˜๋ฉด ๊ทธ๊ฒƒ์€ "data descriptor"๊ฐ€ ์•„๋‹Œ "accessor descriptor"๊ฐ€ ๋œ๋‹ค. accessor-descriptor๋Š” value์™€ writable ์†์„ฑ์ด ๋ฌด์‹œ๋œ๋‹ค. ๋Œ€์‹  configurable์™€ enumerable๋ฅผ ๊ณ ๋ คํ•œ๋‹ค.

var myObject = {
	// define a getter for `a`
	get a() {
		return 2;
	}
};

Object.defineProperty(
	myObject,	// target
	"b",		// property name
	{			// descriptor
		// define a getter for `b`
		get: function(){ return this.a * 2 },

		// make sure `b` shows up as an object property
		enumerable: true
	}
);

myObject.a; // 2

myObject.b; // 4

์™€... ์ด๊ฑด ๋ฌด์—‡์ด๋ƒ.. ๊ฐ์ฒด์— getter๋ฅผ ์„ค์ •ํ•  ์ˆ˜๊ฐ€ ์žˆ์–ด????

var myObject = {
	// define a getter for `a`
	get a() {
		return 2;
	}
};

myObject.a = 3;

myObject.a; // 2

ํ•ญ์ƒ getter, setter๋Š” ๊ฐ™์ด ์ •์˜ํ•ด์ฃผ๋Š”๊ฒŒ ์ข‹๋‹ค.

var myObject = {
	// define a getter for `a`
	get a() {
		return this._a_;
	},

	// define a setter for `a`
	set a(val) {
		this._a_ = val * 2;
	}
};

myObject.a = 2;

myObject.a; // 4

Existence

์šฐ๋ฆฌ๋Š” ๋‹ค์Œ ๊ตฌ๋ฌธ์„ ํ†ตํ•ด ์†์„ฑ์˜ ์กด์žฌ๋ฅผ ํ™•์ธ ํ•  ์ˆ˜ ์žˆ๋‹ค.

var myObject = {
	a: 2
};

("a" in myObject);				// true
("b" in myObject);				// false

myObject.hasOwnProperty( "a" );	// true
myObject.hasOwnProperty( "b" );	// false

in ์—ฐ์‚ฐ์ž๋Š” ๊ฐ์ฒด์— ์†์„ฑ์ด ์žˆ๋Š”์ง€๋‚˜ ์ƒ์œ„ Prototype ์ฒด์ธ ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. ๋ฐ˜๋ฉด hasOwnProperty๋Š” ๊ฐ์ฒด์— ์†์„ฑ์ด ์žˆ๋Š”์ง€๋งŒ ํ™•์ธํ•œ๋‹ค.

Enumeration

var myObject = { };

Object.defineProperty(
	myObject,
	"a",
	// make `a` enumerable, as normal
	{ enumerable: true, value: 2 }
);

Object.defineProperty(
	myObject,
	"b",
	// make `b` NON-enumerable
	{ 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

๊ทธ๋ ‡๋‹ค enumerable์— ์ง‘์ค‘ํ•˜๋ผ false๋Š” enumerable ํ•  ์ˆ˜ ์—†๋‹ค.

์—ด๊ฑฐ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” ๋˜๋‹ค๋ฅธ ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

var myObject = { };

Object.defineProperty(
	myObject,
	"a",
	// make `a` enumerable, as normal
	{ enumerable: true, value: 2 }
);

Object.defineProperty(
	myObject,
	"b",
	// make `b` non-enumerable
	{ enumerable: false, value: 3 }
);

myObject.propertyIsEnumerable( "a" ); // true
myObject.propertyIsEnumerable( "b" ); // false

Object.keys( myObject ); // ["a"]
Object.getOwnPropertyNames( myObject ); // ["a", "b"]

Iteration

๋ณดํ†ต ์›์†Œ ์ถœ๋ ฅํ• ๋•Œ ๋‹ค์Œ๊ณผ ๊ฐ™์ดํ•˜๋Š”๋ฐ

var myArray = [1, 2, 3];

for (var i = 0; i < myArray.length; i++) {
	console.log( myArray[i] );
}
// 1 2 3

์ด๊ฑด ๊ฐ’์„ ๋ฐ˜๋ณตํ•˜๋Š”๊ฒŒ์•„๋‹ˆ๊ณ  ์ธ๋ฑ์Šค๋ฅผ ๋ฐ˜๋ณตํ•˜๋Š”๊ฒƒ์ด๋‹ค.

์ด์— forEach(), every(), some()๋“ฑ์€ ๊ฐ’์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

for in ์€ ๊ฐ’์ด ์•„๋‹Œ ์—ด๊ฑฐ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด ์†์„ฑ์„ ๋ฐ˜๋ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฐ„์ ‘์ ์œผ๋กœ๋งŒ ๊ฐ’์„ ๊ฐ€์ ธ์˜จ๋‹ค.

๊ฐ’์„ ๋ฐ˜๋ณตํ•˜๊ณ  ์‹ถ๋‹ค. ES6์€ of๋ฅผ ์ด์šฉํ•ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•œ๋‹ค.

var myArray = [ 1, 2, 3 ];

for (var v of myArray) {
	console.log( v );
}
// 1
// 2
// 3

for..of ๋ฃจํ”„๋Š” ๋ฐ˜๋ณต ๋  iterator ๊ฐ์ฒด(spec-speak์—์„œ @@iterator๋กœ ์•Œ๋ ค์ง„ ๊ธฐ๋ณธ ๋‚ด๋ถ€ ํ•จ์ˆ˜์—์„œ)๋ฅผ ์š”์ฒญํ•˜๊ณ , ๋ฃจํ”„๋Š” ํ•ด๋‹น iterator ๊ฐ์ฒด์˜ ๋‹ค์Œ ํ˜ธ์ถœ์—์„œ ์—ฐ์†์ ์ธ ๋ฐ˜ํ™˜ ๊ฐ’์„ ๋ฐ˜๋ณตํ•œ๋‹ค.

๋ฐฐ์—ด์—๋Š” ๋‚ด์žฅ @@iterator๊ฐ€ ์žˆ๋‹ค. ์ˆ˜๋™ ๋ฐ˜๋ณต ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

var myArray = [ 1, 2, 3 ];
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 }

@@iterator๋Š” ๋ฐ˜๋ณต๊ธฐ ๊ฐ์ฒด ์ž์ฒด๊ฐ€ ์•„๋‹ˆ๋ผ ๋ฐ˜๋ณต๊ธฐ ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜์ด๋‹ค.

๋ฐ˜๋ณต๊ธฐ์˜ next() ํ˜ธ์ถœ์—์„œ ๋ฐ˜ํ™˜ ๊ฐ’์˜ ํ˜•ํƒœ๋Š” { value: _ , done: _ }์ด๋‹ค. value๋Š” ํ˜„์žฌ ๊ฐ’์ด๊ณ  done์€ bool ๊ฐ’์ด๋‹ค.

for of ์—์„œ๋Š” ์ž๋™์œผ๋กœ ๋ฐ˜๋ณต๋˜์ง€๋งŒ ์ผ๋ฐ˜ ๊ฐ์ฒด์—๋Š” @@iterator๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค. ๋ฐ˜๋ณตํ•˜๋ ค๋Š” ๋ชจ๋“  ๊ฐœ์ฒด์— ๋Œ€ํ•ด ๊ณ ์œ  ํ•œ ๊ธฐ๋ณธ @@ iterator๋ฅผ ์ •์˜ ํ•  ์ˆ˜ ์žˆ๋‹ค.

var myObject = {
	a: 2,
	b: 3
};

Object.defineProperty( 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 {
					value: o[ks[idx++]],
					done: (idx > ks.length)
				};
			}
		};
	}
} );

// iterate `myObject` manually
var it = myObject[Symbol.iterator]();
it.next(); // { value:2, done:false }
it.next(); // { value:3, done:false }
it.next(); // { value:undefined, done:true }

// iterate `myObject` with `for..of`
for (var v of myObject) {
	console.log( v );
}
// 2
// 3

์™€... iterator ๊ตฌํ˜„...

for of๋Š” ES6์˜ ์‚ฌ์šฉ์ž ์ง€์ • iterator์— ๋Œ€์‘ํ•˜๊ธฐ์œ„ํ•œ ๋ฌธ๋ฒ•์ด๋‹ค!

Review (TL;DR)

  1. ๊ฐ์ฒด์—๋Š” ๋งŽ์€ ์˜ต์…˜์ด ์žˆ๋‹ค.
  2. ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋ชจ๋“ ๊ฑด ๊ฐ์ฒด์ด๋‹ค๋ผ๋Š” ์ƒ๊ฐ์€ ํ‹€๋ ธ๋‹ค. ๊ฐ์ฒด๋Š” primitive value์ค‘ ํ•˜๋‚˜์ด๋‹ค.
  3. ๊ฐ์ฒด์—๋Š” ํ•˜์œ„ ์œ ํ˜•์ด ์žˆ๊ณ  [object Array] ์™€ ๊ฐ™์ด ํŠน์ • ๋™์ž‘์— ํŠนํ™”์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.
  4. ๊ฐ์ฒด์—์„œ get push์˜ ์กด์žฌ.
  5. ๊ฐ์ฒด์˜ ์˜ต์…˜์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ๋Š” ์—ฌ๋Ÿฌ ๋ฉ”์†Œ๋“œ๋“ค..
  • Object.preventExtensions(..), Object.seal(..), Object.freeze(..)
  1. ๊ฐ์ฒด์˜ iterator