1 오브젝트의 프로퍼티의 값을 불변하게 해보자
2 오브젝트의 숨은 프로퍼티에 대해 알아보자
3 프로토타입
4 OOP를 프로토타입으로 하는것, 클래스로 하는것 다른가?
5 this를 알아보자

JS 프로토타입

bGV0IGxpc3QgPSBbJ2hlbGxvJywgJ3dvcmxkJ107Ci8vIOydtOugh+qyjCDrsLDsl7TsnYQg66eM65Og64ukCi8vIOq3uOumrOqzoCDqsJzrsJzsnpDrj4TqtawgQ29uc29sZe2DreyXkOyEnCDtmZXsnbjtlbTrs7TrqbQKLy8gMCwgMSwgbGVuZ3RoIOydmCDsho3shLEg7ZmV7J247J20IOqwgOuKpe2VmOqzoCBsZW5ndGjripQg7Ja065Gh6rKM7ZGc7IucKGVudW1lcmFibGU9ZmFsc2Up65CY64qU6rKD7J2EIO2ZleyduO2VoOyImOyeiOuLpAovLyDsl6zquLDsl5DshJwg7ZmV7J2465CcIOyGjeyEseydgCDrqqjrkZAKY29uc29sZS5sb2cobGlzdFsnMCddKQpjb25zb2xlLmxvZyhsaXN0WycxJ10pCmNvbnNvbGUubG9nKGxpc3RbJ2xlbmd0aCddKQoKLy8g7J2065+w7Iud7Jy866GcIOqwkuyXkCDsoJHqt7zsnbQg6rCA64ql7ZWc6rKD7J2064ukCi8vIOydtCDsho3shLHsnZgg66qp66Gd7J2AIOyVhOuemOyZgCDqsJnsnbTrj4Qg7ZmV7J24IOqwgOuKpe2VmOuLpApjb25zb2xlLmxvZyhPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhsaXN0KSkKCi8vIOq3uOufsOuNsC4uCi8vIOq3uOufsOuNsC4uCmNvbnNvbGUubG9nKGxpc3RbJ2ZvckVhY2gnXSkKLy8g7J2066CH6rKMIGZvckVhY2jripQg7J20IOuqqeuhneyXkCDsl4bripTqsoPsnoTsl5Drj4Qg7KCR6re87J20IOqwgOuKpe2VmOuLpAoKY29uc29sZS5sb2coT2JqZWN0LmdldFByb3RvdHlwZU9mKGxpc3QpKQovLyDsnbQg7L2U65Oc66W8IOyLpO2Wie2VtOuztOyekAovLyDqsJ3ssrTqsIAg7ZWY64KYIO2ZleyduOuQmOqzoCDqt7gg7JWI7JeQ64qUIOyXrOufrOqwnOydmCDslrTrkaHqsoztkZzsi5zrkJwg7KaJIGVudW1lcmFibGXtlZjsp4Ag7JWK7J2AIOyGjeyEseuTpOydtCDsl6zrn78g7ZmV7J2465Cg6rKD7J2064ukCi8vIOydtCDspJHsl5AgZm9yRWFjaOuPhCDsnojri6QuCi8vIOq3uOugh+uLpCBsaXN07JeQIOyngeygkSDrtpnslrTsnojripQg7IaN7ISxIOyZuOyXkOuPhCBPYmplY3QuZ2V0UHJvdG90eXBlT2YobGlzdCkg7ZW07IScIOuCmOyYqCDsho3shLHsl5Drj4QgbGlzdFsnZm9yRWFjaCddIOydtOufsOyLneycvOuhnCDsoJHqt7zsnbQg6rCA64ql7ZWc6rKD7J2064ukCgpPYmplY3Quc2V0UHJvdG90eXBlT2YobGlzdCwgeyBmb3JFaWdodDogMTIzIH0pCi8vIOychOydmCDsvZTrk5zrpbwg7IiY7ZaJ7ZWc7ZuEIE9iamVjdC5nZXRQcm90b3R5cGVPZihsaXN0KSDrpqzthLTqsJLsnYQg7ZmV7J247ZW067O066m0IOychOydmCDsvZTrk5zsnZgg65GQ67KI7Ke47J247J6Q66GcIOuEo+ydgCDqsJ3ssrTsnoTsnYQg7ZmV7J247ZWgIOyImCDsnojri6QKCmNvbnNvbGUubG9nKGxpc3RbJ2ZvckVhY2gnXSkKLy8g6re465+wIO2bhCDri6Tsi5wg7ZW067O066m0IO2ZleyduOydtCDslYjrkJzri6QKLy8g6riw7KG07JeQIOu2meyWtOyeiOuNmCDtlITroZzthqDtg4DsnoXsnYQgc2V0UHJvdG90eXBlT2Yg7ZWo7IiY66W8IOydtOyaqe2VtOyEnCB7IGZvckVpZ2h0OiAxMjMgfSDroZwg6rWQ7LK07ZW067KE66C46riwIOuVjOusuOydtOuLpAovLyBsaXN066W8IOunjOuTpOuVjCBsZXQgbGlzdD1bXSDtlbTshJwg67Cw7Je07J2EIOunjOuTpOyWtOyEnCDri7TslZjri6QuIFtd64qUIG5ldyBBcnJheSgp7J2YIOy2leyVve2RnO2YhOydtOuLpAovLyBuZXcgQXJyYXkoKSDtlbTshJwg66eM65OgIOqwneyytOydmCDtlITroZzthqDtg4DsnoXsnYAgQXJyYXkucHJvdG90eXBlIOqzvCDqsJnri6QKCmNvbnNvbGUubG9nKE9iamVjdC5nZXRQcm90b3R5cGVPZihuZXcgQXJyYXkoKSkgPT09IEFycmF5LnByb3RvdHlwZSkKLy8g7J2066CH6rKMIO2ZleyduO2VtOuztOuptCDqsJnsnYwg7ZmV7J2465Cc64ukCi8vIOydtOugh+qyjCDquLDrs7jsoIHsnLzroZwg7KCV7ZW07KC47J6I642YIHByb3RvdHlwZeyduCBBcnJheS5wcm90b3R5cGXrpbwg65a867KE66as6rOgIHsgZm9yRWlnaHQ6IDEyMyB9IOuhnCDqsIjslYTsuZjsm4zrsoTroLjrjZgg6rKD7J2064ukCgpjb25zb2xlLmxvZyhsaXN0Wydmb3JFaWdodCddKQovLyDrgrTqsIAg7J6E7J2Y66GcIOunjOuToCBwcm90b3R5cGXsnLzroZwg6rCI7JWE7LmY7Jug6rOgIOydtCBwcm90b3R5cGXsl5DripQgZm9yRWlnaHTsho3shLHsnbQg7J6I7JeI6riwIOuVjOusuOyXkCDsnITsmYDqsJnsnYAg7KCR6re87Jy866GcIO2ZleyduOydtCDqsIDriqXtlZjri6QKCmNvbnNvbGUubG9nKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKGxpc3QpKQovLyDsho3shLHsnZgg66qp66Gd7J2EIOuztOuptD8gZm9yRWlnaHTripQg7JeG64ukLiBmb3JFaWdodOuKlCBsaXN07J2YIHByb3RvdHlwZeyXkCDsobTsnqztlZjquLAg65WM66y47JeQIOygkeq3vOydtCDqsIDriqXtlojrjZgg6rKD7J2064ukCi8vIGZvckVpZ2h064qUIGxpc3Tsl5Ag7KeB7KCR67aZ7Ja07J6I64qUIOyGjeyEseydtCDslYTri4wgcHJvdG90eXBl7JeQIOyeiOuKlCDsho3shLHsnbTquLAg65WM66y47JeQIGdldE93blByb3BlcnR5TmFtZXMg66GcIO2ZleyduOydtCDslYjrkJzri6QKCmNvbnNvbGUubG9nKGxpc3QuaGFzT3duUHJvcGVydHkoJ2ZvckVpZ2h0JykpCi8vIGZvckVpZ2h064qUIGxpc3Tsl5Ag7KeB7KCR67aZ7Ja07J6I64qUIOyGjeyEseydtCDslYTri4wgcHJvdG90eXBl7JeQIOyeiOuKlCDsho3shLHsnbTquLAg65WM66y47JeQIGhhc093blByb3BlcnR5IOuhnOuPhCDtmZXsnbjsnbQg7JWI65Cc64ukCgpjb25zb2xlLmxvZygnZm9yRWlnaHQnIGluIGxpc3QpCi8vIGluIO2CpOybjOuTnOuhnOuKlCDqsJ3ssrTsl5Ag7KeB7KCRIOu2meyWtOyeiOuKlCDsho3shLHsnbQg7JWE64uI6528IHByb3RvdHlwZeyXkCDsobTsnqztlZjripQg7IaN7ISx7J206528IO2VmOuNlOudvOuPhCDtmZXsnbjsnbQg6rCA64ql7ZWY64ukCgpsZXQgbGlzdDIgPSBbXTsKbGV0IGxpc3QzID0gbmV3IEFycmF5KCk7Ci8vIOymiSDsnIQg65GQ6rCc64qUIOuwsOyXtOqwneyytOulvCDsoJXsnZjtlZjripQg6rCZ7J2AIOuwqeuyleydtOqzoCDsnbTroIfqsowg6rCd7LK066W8IOygleydmO2VmOuptAovLyDqsJ3ssrTsnbTrr4DroZwg7IaN7ISx7J2EIOqwgOyniOyImCDsnojqs6Ag6re4IOyGjeyEseykkSDsiKjsnYDsho3shLHsnbggbGVuZ3Ro6rCAIOuTpOyWtOyeiOydjOuPhCDtmZXsnbjsnbQg6rCA64ql7ZWY66mwCi8vIO2VtOuLuSDrsLDsl7TsnZgg7IaN7ISx7J20IOyVhOuLjCDtlbTri7kg67Cw7Je07J2YIO2UhOuhnO2GoO2DgOyeheyXkCDsoJXsnZjrkJjslrTsnojripQg7IaN7ISx7JeQ64+EIOuniOy5mCDtlbTri7kg67Cw7Je07J2YIOyGjeyEseyXkCDsho3tlbTsnojripQg6rKD7JeQIOygkeq3vO2VmOuKlOqyg+qzvCDqsJnsnYAg7ZiV7YOc7J2YIOy9lOuTnOuhnCDsoJHqt7zsnbQg6rCA64ql7ZWc6rKD7J2064ukCi8vIOq3uOuemOyEnCBsaXN0MlsnZm9yRWFjaCddIOygkeq3vOydtCDqsIDriqXtlojrjZjqsoPsnbTqs6Ag7J206rKD7J2AIGxpc3QyLmZvckVhY2gg66Gc64+EIO2RnO2YhOydtCDqsIDriqXtlZzqsoPsnbTri6QKCmNvbnNvbGUubG9nKE9iamVjdC5nZXRQcm90b3R5cGVPZihsaXN0MikpCi8vIOydtOugh+qyjCDtlITroZzthqDtg4DsnoXsnYQg7ZmV7J247ZW067O066m0IO2UhOuhnO2GoO2DgOyeheqwneyytOyXkCBmb3JFYWNo67+QIOyVhOuLiOudvCBjb25zdHJ1Y3RvcuudvOuKlOqyg+uPhCDsnojri6QKLy8g6re466CH64uk652864qU6rG0IGxpc3QyWydjb25zdHJ1Y3Rvcidd7J2YIOuwqeuyleycvOuhnOuPhCDsoJHqt7zsnbQg6rCA64ql7ZWY64uk64qUIOunkOydtCDrkJzri6QuCi8vIOq3uOufrOuptCDsnbTqsoPsnZgg6rCS7J2AIOustOyXh+ydvOyngCDtmZXsnbjtlbTrs7TsnpAKCmNvbnNvbGUubG9nKGxpc3QyWydjb25zdHJ1Y3RvciddKTsKLy8gQXJyYXkg6rCAIOuCmOyYqOuLpAoKY29uc29sZS5sb2cobGlzdDJbJ2NvbnN0cnVjdG9yJ10gPT09IEFycmF5KTsKLy8g7KaJIGxpc3Qy6rCd7LK066W8IOunjOuTpOq4sCDsnITtlbQg7IKs7Jqp65CY7JeI642YIOyDneyEseyekO2VqOyImCjtgbTrnpjsiqQp6rCAIOustOyXh+yduOyngOulvCDri7Tqs6Dsnojri6Q=
let list = ['hello', 'world']; // 이렇게 배열을 만든다 // 그리고 개발자도구 Console탭에서 확인해보면 // 0, 1, length 의 속성 확인이 가능하고 length는 어둡게표시(enumerable=false)되는것을 확인할수있다 // 여기에서 확인된 속성은 모두 console.log(list['0']) console.log(list['1']) console.log(list['length']) // 이런식으로 값에 접근이 가능한것이다 // 이 속성의 목록은 아래와 같이도 확인 가능하다 console.log(Object.getOwnPropertyNames(list)) // 그런데.. // 그런데.. console.log(list['forEach']) // 이렇게 forEach는 이 목록에 없는것임에도 접근이 가능하다 console.log(Object.getPrototypeOf(list)) // 이 코드를 실행해보자 // 객체가 하나 확인되고 그 안에는 여러개의 어둡게표시된 즉 enumerable하지 않은 속성들이 여럿 확인될것이다 // 이 중에 forEach도 있다. // 그렇다 list에 직접 붙어있는 속성 외에도 Object.getPrototypeOf(list) 해서 나온 속성에도 list['forEach'] 이런식으로 접근이 가능한것이다 Object.setPrototypeOf(list, { forEight: 123 }) // 위의 코드를 수행한후 Object.getPrototypeOf(list) 리턴값을 확인해보면 위의 코드의 두번째인자로 넣은 객체임을 확인할 수 있다 console.log(list['forEach']) // 그런 후 다시 해보면 확인이 안된다 // 기존에 붙어있던 프로토타입을 setPrototypeOf 함수를 이용해서 { forEight: 123 } 로 교체해버렸기 때문이다 // list를 만들때 let list=[] 해서 배열을 만들어서 담았다. []는 new Array()의 축약표현이다 // new Array() 해서 만든 객체의 프로토타입은 Array.prototype 과 같다 console.log(Object.getPrototypeOf(new Array()) === Array.prototype) // 이렇게 확인해보면 같음 확인된다 // 이렇게 기본적으로 정해져있던 prototype인 Array.prototype를 떼버리고 { forEight: 123 } 로 갈아치워버렸던 것이다 console.log(list['forEight']) // 내가 임의로 만든 prototype으로 갈아치웠고 이 prototype에는 forEight속성이 있었기 때문에 위와같은 접근으로 확인이 가능하다 console.log(Object.getOwnPropertyNames(list)) // 속성의 목록을 보면? forEight는 없다. forEight는 list의 prototype에 존재하기 때문에 접근이 가능했던 것이다 // forEight는 list에 직접붙어있는 속성이 아닌 prototype에 있는 속성이기 때문에 getOwnPropertyNames 로 확인이 안된다 console.log(list.hasOwnProperty('forEight')) // forEight는 list에 직접붙어있는 속성이 아닌 prototype에 있는 속성이기 때문에 hasOwnProperty 로도 확인이 안된다 console.log('forEight' in list) // in 키워드로는 객체에 직접 붙어있는 속성이 아니라 prototype에 존재하는 속성이라 하더라도 확인이 가능하다 let list2 = []; let list3 = new Array(); // 즉 위 두개는 배열객체를 정의하는 같은 방법이고 이렇게 객체를 정의하면 // 객체이므로 속성을 가질수 있고 그 속성중 숨은속성인 length가 들어있음도 확인이 가능하며 // 해당 배열의 속성이 아닌 해당 배열의 프로토타입에 정의되어있는 속성에도 마치 해당 배열의 속성에 속해있는 것에 접근하는것과 같은 형태의 코드로 접근이 가능한것이다 // 그래서 list2['forEach'] 접근이 가능했던것이고 이것은 list2.forEach 로도 표현이 가능한것이다 console.log(Object.getPrototypeOf(list2)) // 이렇게 프로토타입을 확인해보면 프로토타입객체에 forEach뿐 아니라 constructor라는것도 있다 // 그렇다라는건 list2['constructor']의 방법으로도 접근이 가능하다는 말이 된다. // 그러면 이것의 값은 무엇일지 확인해보자 console.log(list2['constructor']); // Array 가 나온다 console.log(list2['constructor'] === Array); // 즉 list2객체를 만들기 위해 사용되었던 생성자함수(클래스)가 무엇인지를 담고있다