GitHub์ ์๋ 33 Concepts Every JavaScript Developer Should Know ๋ผ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ด์ฉ ์ค ๊ณต๋ถํ๊ณ ์ถ์ ์ํฐํด์ ๋ด๊ฐ ์ ๋ฆฌํ ๊ฒธ ๊ธฐ์ตํ ๊ฒธ ์์ฑํ๋ ๋ฒ์ญ๊ธ์ด๋ค. 33๊ฐ์ง ์ค ๋ ๋ฒ์งธ์ธ ๊ธฐ๋ณธํ๊ณผ ๊ด๋ จ๋ ๋ด์ฉ์ด๋ค.
โป ๋ด๋ณด๋ด๋ฒ(๋ด๊ฐ ๋ณด๋ ค๊ณ ๋ด๊ฐ ๋ฒ์ญํ): ์์ด ์ ๊ณต์๋ ํด์ธ ์ ํํ๋ ์๋๊ธฐ์ ๋ฒ์ญ์๋ ์์ญ, ์ค์ญ, ๊ตฌ๊ธ ๋ฒ์ญ์ด ๋ฌด์ํ ๋ง์ ์ ์์ผ๋ฉฐ, ์คํ๋ ๋ง์ ์ ์๋ค. ์ ํํ ๋ด์ฉ์ ์๋ฌธ์ ์ง์ ์ดํด๋ณด๊ฑฐ๋ ๋ค๋ฅธ ์ ๋ณด๋ค์ ๋ ์ฐพ์๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
(ํ์ง๋ง ๋๊ธ ํผ๋๋ฐฑ๋ ํ์ํฉ๋๋ค๐ )
์ด๋ฒ์ ๊ณ ๋ฅธ ์ํฐํด์ Angus Croll ๋์ด ์์ฑํ์ The Secret Life of JavaScript Primitives ์ด๋ค. ์ํฐํด ๋ด์ฉ์ ํ์ด๋ดค์ ๋ ์ ๋๋ก ๋ฒ์ญํ ์ ์์์ง ๊ณ ๋ฏผ์ด ๋๊ธดํ์ง๋ง.... ๋ด์ฉ์ด ์ข์์ ํด๋ณด๊ธฐ๋ก ํ๋ค. ๋ด์ฉ ์ค๊ฐ ์ค๊ฐ ๐ค์ด ์์ด์ฝ์ ๋ณธ๋ฌธ์ ๋์ ์์ง ์์ ๋ฒ์ญํ๋ฉฐ ์ถ๊ฐํ ๋ง์ด๋ค.
The Secret Life of JavaScript Primitives
You may not know it but, in JavaScript, whenever you interact with string, number or boolean primitives you enter a hidden world of object shadows and coercion. So dust off your Sherlock Holmes out…
javascriptweblog.wordpress.com
์ด๋ฏธ ์ ์๋ ์์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ์์ string, number ํน์ boolean ๊ธฐ๋ณธํ์ผ๋ก ์ํธ์์ฉํ ๋์ ๋น์ ์ ๊ฐ์ฒด์ ๊ทธ๋ฆผ์์ ๊ฐ์ ํ ๋ณํ(coerce)์ ์จ๊ฒจ์ง ์ธ๊ณ๋ก ๋ค์ด๊ฐ๋ค. ๊ทธ๋ฌ๋ ๋ฐฉ์นํด๋๋ ๋น์ ์ ์ ๋ก ํ์ฆ ๋ณต์ฅ์ ๊บผ๋ด์ด ๊ณ์ ์ฝ์ด๋ณด๋ผ. (๐ค: ํ์ ๊ฐ์ ๋ง์์ผ๋ก ์จ๊ฒจ์ง ์ธ๊ณ๋ฅผ ์์๋ณด์๋ ์๋ฏธ์ธ๋ฏ...)
๊ธฐ๋ณธ
๊ฐ์ฒด(Objects)๋ ์์ฑ์ ์งํฉ์ด๋ค. ์์ฑ์ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ ์๋, ๊ธฐ๋ณธํ์ผ ์๋ ์๋ค. ๊ธฐ๋ณธํ์ ๊ฐ์ด๊ณ ์์ฑ์ ๊ฐ์ง๊ณ ์์ง ์๋ค.
์๋ฐ์คํฌ๋ฆฝํธ์๋ 5๊ฐ์ง์ ๊ธฐ๋ณธํ์ด ์๋ค: undefined, null, boolean, string ๊ทธ๋ฆฌ๊ณ number์ด๋ค. ๊ทธ ๋ฐ์ ๋ชจ๋ ๊ฒ๋ค์ ๊ฐ์ฒด์ด๋ค. Boolean, string๊ณผ number ๊ธฐ๋ณธํ๋ค์ ๊ทธ๋ค์ ๊ฐ์ฒด ๋์๋ถ๋ก ๊ฐ์ธ์ง ์ ์๋ค (๐ค: ์๋์ ์์ ์ฝ๋ ์ฐธ์กฐ). ์ด ๊ฐ์ฒด๋ค์ ๊ฐ๊ฐ Boolean, String, Number ์์ฑ์์ ์ธ์คํด์ค์ด๋ค.
typeof true; //"boolean"
typeof Boolean(true); //"boolean"
typeof new Boolean(true); //"object"
typeof (new Boolean(true)).valueOf(); //"boolean"
typeof "abc"; //"string"
typeof String("abc"); //"string"
typeof new String("abc"); //"object"
typeof (new String("abc")).valueOf(); //"string"
typeof 123; //"number"
typeof Number(123); //"number"
typeof new Number(123); //"object"
typeof (new Number(123)).valueOf(); //"number"
๋ง์ผ ๊ธฐ๋ณธํ์ ์์ฑ์ด ์๋ค๋ฉด, ์ "abc".length์ ๊ฐ์ ๋ฐํํ๋๊ฐ?
๊ทธ ์ด์ ๋ ์๋ฐ์คํฌ๋ฆฝํธ๋ ๊ธฐ๋ณธํ๊ณผ ๊ฐ์ฒด ์ฌ์ด์์ ์ฝ๊ฒ ๊ฐ์ ํ ๋ณํํ๊ธฐ ๋๋ฌธ์ด๋ค. ์ด ๊ฒฝ์ฐ์ ๋ฌธ์์ด ๊ฐ์ ๊ธธ์ด ์์ฑ์ ์ ๊ทผํ๊ธฐ ์ํด์ ๋ฌธ์์ด ๊ฐ์ฒด๋ก ๊ฐ์ ํ ๋ณํํ๋ค. ์ด ๋ฌธ์์ด ๊ฐ์ฒด๋ ์์๊ฐ์ ์ฌ์ฉ์ด ๋๊ณ ๊ทธ ํ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ์ ์ ์ํด์ ํฌ์๋๋ค - ํ์ง๋ง TV ๋์ค์ปค๋ฒ๋ฆฌ ์ผ ์ ์ (๐ค: ๋์ค์ปค๋ฒ๋ฆฌ ์ฑ๋์ ๋์ค๋ ์ผ๋ค์ ๋งํ๋ ๊ฒ ๊ฐ์)์ผ๋ก, ์ ์ฒด๋ถ๋ช ์ ์๋ช ์ฒด๋ฅผ ์ก์์ ์ถ๊ฐ์ ์ผ๋ก ๋ถ์ํ๊ธฐ ์ํด ๋ณด์กดํ ๊ฒ์ด๋ค...
String.prototype.returnMe= function() {
return this;
}
var a = "abc";
var b = a.returnMe();
a; //"abc"
typeof a; //"string" (still a primitive)
b; //"abc"
typeof b; //"object"
...๊ทธ๋ฆฌ๊ณ ๋ง์ ์๋ฏธ์๋ ๊ณผํ์ ์กฐ์ฌ๋ค๋ก ์ฐ๋ฆฌ๋ ์ด์ ์ฌ๋ฌผ์ ์์ฐ์ ์ธ ์งํ์ ๋ฐฉํดํ๊ณ b๊ฐ ์ฃผ๋ณ์ ์๋ ํ ๊ฐ์ฒด๊ฐ ๊ฐ๋น์ง ์ปฌ๋ ํธ๋๋ ๊ฒ์ ๋ง์๋ค. ํ์ด์ ๋ฒ ๋ฅดํฌ๋ ์ด์์๊ณ ๊ฑด๊ฐํ๋ค๐(๐ค: ํ์ด์ ๋ฒ ๋ฅดํฌ๋ ์์์ญํ์ ์ฐฝ์์๋ผ๊ณ ํ๋ค.)
(strict mode์์๋ ์ ์ฒด๋ถ๋ช ์ ์๋ช ์ฒด๊ฐ ์ฌ๋ผ์ง๋ค - thanks @DmitrySoshnikov) (๐ค: ๋๊ธ์ ์ธ๊ธ๋ ๋ด์ฉ์ ์ ๋ฐ์ดํธ ํด์ฃผ์ ๋ฏ)
์ฌ๊ธฐ ๋ ํ๊ฒฝ์ ์ธ ๊ฐ๋น์ง ์ปฌ๋ ์ ๋ฐฉํด ์์ด ๊ฐ์ฒด ํ์ ์ ์ฆ๋ช ํ๋ ๋ณด๋ค ํ๊ฒฝ์ ์ผ๋ก ์ฑ ์์ ์ง๋ ์์๊ฐ ์๋ค:
Number.prototype.toString = function() {
return typeof this;
}
(123).toString(); //"object"
์ด๋ฅผ ํตํด ๊ธฐ๋ณธํ์ ๊ฐ๊ฐ์ ๊ฐ์ฒด ์์ฑ์์ ์ํด ์ ์๋ ๋ชจ๋ ์์ฑ (๋ฉ์๋๋ฅผ ํฌํจ) ์ ์ ๊ทผํ ์ ์๋ค.
์ด ๊ฐ์ฒด๋ค์ ๊ฐ์ผ๋ก๋ ๊ฐ์ ํ ๋ณํ๋ ์ ์๋๊ฐ?
๊ทธ๋ ๋ค. ๊ฑฐ์. ์ด ํํ์ ๊ฐ์ฒด๋ค์ ๋จ์ํ ์ธ๋ ๊ฒ์ด๋ค. ๊ฐ์ฒด๋ค์ ๊ฐ์ ๊ฐ์ธ๊ณ ์๋ ๊ธฐ๋ณธํ์ด๊ณ ์ผ๋ฐ์ ์ผ๋ก ํ์์ ๋ฐ๋ผ ์ด ๊ฐ์ผ๋ก ๊ฐ์ ํ ๋ณํ๋ ๊ฒ์ด๋ค. ์์ธํ ๋ด์ฉ์ ์ด ๊ธฐ์ฌ๋ฅผ ์ฐธ์กฐํ๋ผ.
//object coerced to primitive
var Twelve = new Number(12);
var fifteen = Twelve + 3;
fifteen; //15
typeof fifteen; //"number" (primitive)
typeof Twelve; //"object"; (still object)
//another object coerced to primitive
new String("hippo") + "potamus"; //"hippopotamus"
//object not coerced (because 'typeof' operator can work with objects)
typeof new String("hippo") + "potamus"; //"objectpotamus"
์ฌํ๊ฒ๋ boolean ๊ฐ์ฒด๋ ์ฝ๊ฒ ๊ฐ์ ํ ๋ณํ๋์ง ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ์์ฒ์ ๋ชจ์์ ๋ํด boolean ๊ฐ์ฒด๋ ๊ฐ์ด null์ด๋ undefined๊ฐ ์๋๊ณ ์๋ true๋ก ํํ๋๋ค. ์๋ ๋ด์ฉ์ ์๋ํด๋ณด๋ผ:
if (new Boolean(false)) {
alert("true???");
}
์ผ๋ฐ์ ์ผ๋ก boolean ๊ฐ์ฒด์ ๊ทธ๋ค์ ๊ฐ์ ๋ช ์์ ์ผ๋ก ์์ฒญํด์ผํ๋ค. ์๋์ ๋ด์ฉ์ด ๊ฐ์ด "๊ฑฐ์ง"์ "์ง์ค"์ธ์ง ์ฌ๋ถ๋ฅผ ๊ฒฐ์ ์ง๋๋ฐ ์ ์ฉํ ์๋ ์๋ค.
var a = "";
new Boolean(a).valueOf(); //false
...ํ์ง๋ง ์ค์ ๋ก ์ด๋ ๊ฒ ํ๋๊ฒ ๋ ์ฝ๋ค.
var a = Boolean("");
a; //false
... ํน์ ์ด๋ ๊ฒ๋
var a = "";
!!a; //false
๊ฐ์ ํ ๋ณํ๋ฅผ ์ฌ์ฉํ๋ฉด ๊ธฐ๋ณธํ์ ๊ฐ์ ํ ๋นํ๋ ๊ฒ์ ํ์ฉํ๋๊ฐ?
์๋๋ค.
var primitive = "september";
primitive.vowels = 3;
primitive.vowels; //undefined;
๋ง์ผ ์๋ฐ์คํฌ๋ฆฝํธ๊ฐ ๊ธฐ๋ณธ๊ฐ์ ์์ฑ์ ํ ๋นํ๋ ค๋ ์๋๋ฅผ ๊ฐ์งํ๋ฉด, ์๋ฐ์คํฌ๋ฆฝํธ๋ ์ค์ ๋ก ๊ธฐ๋ณธ๊ฐ์ ๊ฐ์ฒด๋ก ๊ฐ์ ํ ๋ณํํ๋ค. ํ์ง๋ง, ์ด์ ์์ ์์์ฒ๋ผ, ์ด ์๋ก์ด ๊ฐ์ฒด๋ ์ฐธ์กฐ๋ ๊ฒ์ด ์๊ธฐ ๋๋ฌธ์ ์ฆ์ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ ๋จน์ด๊ฐ ๋๋ค.
์ฌ๊ธฐ ์ค์ ๋ก ๋ฌด์์ด ์ผ์ด๋๋์ง๋ฅผ ์ค๋ช ํ๊ธฐ ์ํด์ ๊ฐ์ ์์ ๋ฅผ ์์ฌ ์ฝ๋๋ก ํํํด ๋์๋ค.
var primitive = "september";
primitive.vowels = 3;
//new object created to set property
(new String("september")).vowels = 3;
primitive.vowels;
//another new object created to retrieve property
(new String("september")).vowels; //undefined
๋ณด๋ค์ํผ ์ธ๋ชจ์์ ๋ฟ๋ง ์๋๋ผ ๊ฝค ๋ญ๋น์ด๋ค.
์ ๋ฆฌ
์์ฑ์ ํ ๋นํ๋ ๋ฅ๋ ฅ์ ๊ธฐ๋ณธํ์ ๋นํด ๊ฐ์ฒด๋ง์ ์ ์ผํ ์ฅ์ ์ด์ง๋ง ์ค์ ๋ก๋ ์ด๊ฒ๋ง์ ์์ฌ์ค๋ฝ๋ค. String, boolean ๊ทธ๋ฆฌ๊ณ number๋ ๊ตฌ์ฒด์ ์ด๊ณ ์ ์ ์๋ ๋ชฉ์ ์ ๊ฐ์ง๊ณ ์๊ณ ๊ทธ๊ฒ๋ค์ ์ฃผ ๋ณด์ ์๋ก ์ฌ์ ์ํ๋ ๊ฒ์ ์ฌ๋๋ค์ ํผ๋์ค๋ฝ๊ฒ ํ ๊ฒ์ด๋ค. ๊ฒ๋ค๊ฐ ๊ธฐ๋ณธํ์ ๋ถ๋ณ์ด๊ธฐ ๋๋ฌธ์ ๊ฐ์ฒด๋ก ๊ฐ์ธ์ ์์ฑ์ ์์ ํ ์ ์๋ค.
var me = new String("Angus");
me.length = 2; //(error in strict mode)
me.length; //5 (not 2 - thanks @joseanpg)
me.valueOf(); "Angus"
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ๋๋ ๊ธฐ๋ณธํ๊ณผ ๊ธฐ๋ณธํ๊ณผ ์ํธ์์ฉ์ ๋ด๋ถ์์๋ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์ง ์ผ์ ๋ํด ์ ์ดํดํ๋ ๊ฒ์ด ์ธ์ด์ ๋ ๊น์ ์ง์์ ํฅํ ์ค์ํ ๋จ๊ณ๋ผ๊ณ ์๊ฐํ๋ค. ์ด ๋ด์ฉ์ด ๋์์ด ๋์๊ธธ ๋ฐ๋๋ค.