GitHub์ ์๋ 33 Concepts Every JavaScript Developer Should Know ๋ผ๋ ๋ฆฌํฌ์งํ ๋ฆฌ์ ๋ด์ฉ ์ค ๊ณต๋ถํ๊ณ ์ถ์ ์ํฐํด์ ๋ด๊ฐ ์ ๋ฆฌํ ๊ฒธ ๊ธฐ์ตํ ๊ฒธ ์์ฑํ๋ ๋ฒ์ญ๊ธ์ด๋ค. 33๊ฐ์ง ์ค ๋ ๋ฒ์งธ์ธ ๊ธฐ๋ณธํ๊ณผ ๊ด๋ จ๋ ๋ด์ฉ์ด๋ค.
โป ๋ด๋ณด๋ด๋ฒ(๋ด๊ฐ ๋ณด๋ ค๊ณ ๋ด๊ฐ ๋ฒ์ญํ): ์์ด ์ ๊ณต์๋ ํด์ธ ์ ํํ๋ ์๋๊ธฐ์ ๋ฒ์ญ์๋ ์์ญ, ์ค์ญ, ๊ตฌ๊ธ ๋ฒ์ญ์ด ๋ฌด์ํ ๋ง์ ์ ์์ผ๋ฉฐ, ์คํ๋ ๋ง์ ์ ์๋ค. ์ ํํ ๋ด์ฉ์ ์๋ฌธ์ ์ง์ ์ดํด๋ณด๊ฑฐ๋ ๋ค๋ฅธ ์ ๋ณด๋ค์ ๋ ์ฐพ์๋ณด๋ ๊ฒ์ ์ถ์ฒํ๋ค.
(ํ์ง๋ง ๋๊ธ ํผ๋๋ฐฑ๋ ํ์ํฉ๋๋ค๐ )
์ด๋ฒ์ ๊ณ ๋ฅธ ์ํฐํด์ Angus Croll ๋์ด ์์ฑํ์ The Secret Life of JavaScript Primitives ์ด๋ค. ์ํฐํด ๋ด์ฉ์ ํ์ด๋ดค์ ๋ ์ ๋๋ก ๋ฒ์ญํ ์ ์์์ง ๊ณ ๋ฏผ์ด ๋๊ธดํ์ง๋ง.... ๋ด์ฉ์ด ์ข์์ ํด๋ณด๊ธฐ๋ก ํ๋ค. ๋ด์ฉ ์ค๊ฐ ์ค๊ฐ ๐ค์ด ์์ด์ฝ์ ๋ณธ๋ฌธ์ ๋์ ์์ง ์์ ๋ฒ์ญํ๋ฉฐ ์ถ๊ฐํ ๋ง์ด๋ค.
์ด๋ฏธ ์ ์๋ ์์ง๋ง, ์๋ฐ์คํฌ๋ฆฝํธ์์ 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"
๊ทธ๋ผ์๋ ๋ถ๊ตฌํ๊ณ ๋๋ ๊ธฐ๋ณธํ๊ณผ ๊ธฐ๋ณธํ๊ณผ ์ํธ์์ฉ์ ๋ด๋ถ์์๋ ๋ฌด์จ ์ผ์ด ๋ฒ์ด์ง๋์ง ์ผ์ ๋ํด ์ ์ดํดํ๋ ๊ฒ์ด ์ธ์ด์ ๋ ๊น์ ์ง์์ ํฅํ ์ค์ํ ๋จ๊ณ๋ผ๊ณ ์๊ฐํ๋ค. ์ด ๋ด์ฉ์ด ๋์์ด ๋์๊ธธ ๋ฐ๋๋ค.