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

JS this를 알아보자

Ly8gdGhpc+ulvCDslYzslYTrs7TsnpAKLy8g7J206rGwIOyViOyWtOugteuLpAovLyDsnbQg6riA7JeQ7ISc64qUIOyViOyWtOugteqyjCDtlaDqsbDri6QKLy8g7J20IOq4gCDrs7TquLDsoITsl5Ag7J2864uoIOqwneyytOuekSDtlajsiJjsnZgg6riw67O47J2AIOyVjOyVhOyVvO2VnOuLpAovLyDrqqjrpbTrqbQg66i87KCAIOqwneyytOuekSDtlajsiJjsgqzsmqnrsKnrspUg66i87KCAIOyVjOqzoCDsmKTsnpAKCmxldCBvYmplY3QgPSB7CiAgIG1ldGhvZDogZnVuY3Rpb24gKCkgewogICAgICBjb25zb2xlLmxvZygnSGVsbG8nKQogICB9LAogICBhcnJvdzogKCkgPT4gewogICAgICBjb25zb2xlLmxvZygnQXJyb3cnKQogICB9Cn0KLy8g7J2066CH6rKMIOqwneyytOulvCDrp4zrk6Tqs6AgbWV0aG9k7IaN7ISx7JeQIO2VqOyImOulvCDri7TsnYQg7IiYIOyeiOuLpAovLyBhcnJvd+yGjeyEseyXkOuPhCDtlajsiJjrpbwg64u07JWY64ukCi8vIO2VqOyImOuqqOyKteydtCDrkZDqsJzqsIAg64uk66W064ukLgovLyDqt7jrnpjrj4Qg7J2864uoIOuRmOuLpCDtlajsiJjri6QKLy8gKCk9Pnt9IOydtOqxtCDtmZTsgrTtkZztlajsiJjrnbzqs6Ag7ZWc64ukCgpvYmplY3QubWV0aG9kCm9iamVjdC5hcnJvdwovLyDsnbTroIfqsowg7KCR6re87ZWgIOyImCDsnojri6QKLy8g7J206rKD7J2AIO2VqOyImOydtOuLpAovLyDtlajsiJgg65Kk7JeQICgpIOulvCDrtpnsnbTrqbQg7Iuk7ZaJ7ZWgIOyImCDsnojri6QKCm9iamVjdC5tZXRob2QoKQpvYmplY3QuYXJyb3coKQovLyDsi6Ttlontlojri6QKLy8g7Iuk7ZaJ7ZWY66m0IOqwgeqwgSBIZWxsb+uekSBBcnJvd+qwgCDsvZjshpTsl5Ag7LCN7Z6M64ukCgpsZXQgb2JqZWN0MiA9IHsKICAgbWV0aG9kOiBmdW5jdGlvbiAoKSB7CiAgICAgIGNvbnNvbGUubG9nKHRoaXMpCiAgIH0sCiAgIGFycm93OiAoKSA9PiB7CiAgICAgIGNvbnNvbGUubG9nKHRoaXMpCiAgIH0KfQovLyBIZWxsb+uekSBBcnJvd+uMgOyLoOyXkCB0aGlz652864qU6rG4IOuEo+yWtOuztOyekApvYmplY3QyLm1ldGhvZCgpCm9iamVjdDIuYXJyb3coKQovLyBvYmplY3QyLm1ldGhvZCgpIOulvCDsi6TtlontlojsnYTrlYzripQgLm1ldGhvZCgpIOyVnuyXkCDsnojripQgb2JqZWN0MuqwgCB0aGlz6rCAIOuQnOuLpAovLyBvYmplY3QyLmFycm93KCkg66W8IOyLpO2Wie2WiOydhOuVjOuKlCAuYXJyb3coKSDslZ7sl5Ag7J6I64qUIG9iamVjdDLqsIAgdGhpc+qwgCDrkJjripTqsoPsnbQg7JWE64uI64ukCi8vIOq3uOufvCBvYmplY3QyLmFycm93KCkg66W8IOyLpO2Wie2WiOydhOuVjOuKlCB0aGlz64qUIOyWtOuWu+qyjCDrkJjripTqsbDsp4AuLj8g7JeQIOuMgO2VnCDsnbTslbzquLDripQg7J6g7IucIOuSpOuhnO2VmOyekAoKZnVuY3Rpb24gbWV0aG9kKCkgewogICBjb25zb2xlLmxvZyh0aGlzLnZhbCk7Cn0KbGV0IG9iajEgPSB7IG1ldGhvZDogbWV0aG9kLCB2YWw6IDEgfTsKbGV0IG9iajIgPSB7IG1ldGhvZDogbWV0aG9kLCB2YWw6IDIgfTsKLy8g7J6QIOydtOugh+qyjCDsvZTrk5zrpbwg7KSA67mE7ZW067Sk64ukCi8vIG9iajEsIG9iajIg6rCd7LK07JeQIOuLtOyVhOykgCBtZXRob2TripQg6rKw6rWtIOqwmeydgCDtlajsiJjrpbwg7J2Y66+47ZWc64ukCgpjb25zb2xlLmxvZyhvYmoxLm1ldGhvZCA9PT0gb2JqMi5tZXRob2QpCi8vIOqwmeuLpAoKb2JqMS5tZXRob2QoKTsKb2JqMi5tZXRob2QoKTsKLy8g6re466CH64uk66m0IOydtOugh+qyjCDtlZjrqbQg7Iuk7ZaJ7ZWY64qUIO2VqOyImOqwgCDqsJnri6TripQg65y77J2064ukCi8vIG1ldGhvZCDtlajsiJjrpbwg7Iuk7ZaJ7ZWY66m0IHRoaXMudmFsIOydhCDsvZjshpTsl5Ag7LCN6rKMIOuQmOyWtOyeiOuLpAovLyDqt7jrn7DrjbAg6rKw6rO866W8IOuztOuptCDqsIHqsIEg64uk66W4IOqwkuydtCDssI3tmIDsnojripTqsoPsnbQg7ZmV7J2465Cc64ukCi8vIOqwmeydgCDtlajsiJjrpbwg7Iuk7ZaJ7ZaI64qU642wIOqysOqzvOqwgCDri6TrpbTri6QKLy8g7J2065+wIOywqOydtOulvCDrp4zrk6DqsoPsnYAg7Ja065a76rKMIOyLpO2Wie2WiOuKlOyngOyXkCDsnZjtlbQg7KCV7ZW07KeE6rKD7J2064ukCi8vIC5tZXRob2QoKSDslZ7sl5Ag66y07JeH7J20IOyZlOuKlOyngOyXkCDsnZjtlbTshJwgdGhpc+qwgCDqsrDsoJXrkJzqsoPsnbTri6QKCmZ1bmN0aW9uIGhlbGxvKCkgeyBjb25zb2xlLmxvZygnaGVsbG8nKSB9CmZ1bmN0aW9uIGhlbGxvMigpIHsgY29uc29sZS5sb2coJ2hlbGxvMicpIH0KZnVuY3Rpb24gaGVsbG8zKCkgeyB0aGlzKCk7IH0KaGVsbG8ubWV0aG9kID0gaGVsbG8zOwpoZWxsbzIubWV0aG9kID0gaGVsbG8zOwpoZWxsby5tZXRob2QoKQpoZWxsbzIubWV0aG9kKCkKLy8g7J206rKD64+EIOqwmeydgCDsnbTslbzquLDri6QKLy8g7ZWo7IiY65287ZWY642U652864+EIO2VqOyImOuPhCDqsJ3ssrTsnbTrr4DroZwgaGVsbG8ubWV0aG9kIOyZgCDqsJnsnYAg7Iud7Jy866GcIOyGjeyEseulvCDrp4zrk6TslrTspITsiJjsnojri6QKLy8g7J20IOyGjeyEseyXkCDtlajsiJjrpbwg64u07JWY6rOgIOychOyZgOqwmeydgCDrsKnrspXsnLzroZwgIOyLpO2Wie2WiOuLpAovLyBoZWxsby5tZXRob2QoKSDsnbTroIfqsowg7Iuk7ZaJ7IucIG1ldGhvZCDtlajsiJgg7KaJIGhlbGxvM+2VqOyImOyXkOyEnOydmCB0aGlz64qUIOyLpO2Wie2VtOyjvOuKlCDsi5zsoJDsl5AgLm1ldGhvZCgpIOyVnuyXkCDsnojripTqsoPsnbQg65Cc64ukCi8vIOymiSB0aGlz64qUIGhlbGxv6rCAIOuQnOuLpC4gaGVsbG/ripQg7ZWo7IiY7J2066+A66GcIHRoaXMoKSDsnZgg67Cp67KV7Jy866GcIO2VqOyImOulvCDsi6TtlontlaAg7IiYIOyeiOuKlOqyg+ydtOuLpAoKbGV0IG9iajMgPSB7CiAgIG1ldGhvZDogZnVuY3Rpb24gKCkgewogICAgICBsZXQgb2JqNCA9IHsKICAgICAgICAgbWV0aG9kMjogKCkgPT4gewogICAgICAgICAgICByZXR1cm4gdGhpczsKICAgICAgICAgfQogICAgICB9OwogICAgICByZXR1cm4gb2JqNC5tZXRob2QyKCk7CiAgIH0KfQpjb25zb2xlLmxvZyhvYmozLm1ldGhvZCgpID09PSBvYmozKTsKLy8g65Kk66GcIOuvuOukhOuSgOuNmCDtmZTsgrTtkZztlajsiJjrpbwg67O07J6QCi8vIOydtCDsvZTrk5zripQgdHJ1ZeqwgCDrgpjsmKjri6QKLy8gb2JqMy5tZXRob2QoKSDrpbwg7Iuk7ZaJ7ZWY6rKM65CY66m0IC5tZXRob2QoKSDslZ7sl5Agb2JqM+ydtCBtZXRob2Qg7ZWo7IiYIOyViOyXkOyEnCB0aGlz6rCAIOuQnOuLpAovLyBtZXRob2Qg7ZWo7IiYIOyViOyXkOyEnOuKlCDrmJAgb2JqNC5tZXRob2QyKCkg7J2065+w7Iud7J2YIOy9lOuTnOqwgCDsi6TtlonrkJjqsowg65CY64qU642wIOydtOuVjCBtZXRob2QyIO2VqOyImCDslYjsl5DshJwgdGhpc+uKlCDtlajsiJgg7Iuk7ZaJ7L2U65Oc7JeQ7IScIC5tZXRob2QyKCkg7JWe7J2YIG9iajTrpbwg7J2Y66+47ZWY6rKMIOuQmOyngOyViuuKlOuLpAovLyDqt7jrn7Ag7J207Jyg64qUIG1ldGhvZDLripQg7ZmU7IK07ZGcIO2VqOyImOydtOq4sCDrlYzrrLjsnbTri6QuIOq3uOufrOuptCB0aGlz64qUIOustOyXh+ydtCDrkJjripTqsIAgb2JqM+ydtCDrkJzri6QKCi8vIOyngOq4iOq5jOyngOydmCDqsrDqs7zrpbwg67O066m0IHRoaXPripQgdGhpc+ulvCDtj6ztlajtlZwg7ZWo7IiY6rCAIOyWtOuWpOyLneycvOuhnCDsi6TtlonrkJjripDrg5Dsl5Ag65Sw6528IOq3uCDsnZjrr7jqsIAg7KCV7ZW07KeA64qU6rKD7J2EIO2ZleyduO2WiOuLpAovLyDslYTrnpjsnZgg7L2U65Oc64qUIOyigCDrs7XsnqHtlaDsiJjrj4Qg7J6I7Jy864uIIOq3uOuDpSDqsIDrs43qsowg67O07J6QLgovLyDsnbTtlbTrpbwg6rytIO2VmOyngCDslYrslYTrj4Qg65Cc64ukCgpsZXQgb2JqID0gewogICBzdHI6ICdoZWxsbycsCiAgIHN1bTogQXJyYXkucHJvdG90eXBlLmpvaW4sCiAgIGdldCBsZW5ndGgoKSB7CiAgICAgIC8vIG9iai5zdW0oJy8nKSDtlbTshJwg7Iuk7ZaJ7IucCiAgICAgIC8vIOyEuOq1sOuNsOydmCB0aGlz64qUIG9iauqwgCDrkJzri6QKICAgICAgLy8gam9pbu2VqOyImOyXkOyEnOuKlCB0aGlzLmxlbmd0aOuhnCDsoJHqt7ztlZjqs6Ag7J6I7J2E6rKD7J20652864qU6rKDIOynkOyeke2VoCDsiJgg7J6I64ukCiAgICAgIC8vIHRoaXPripQgb2Jq7J2066+A66GcIG9iai5sZW5ndGjrpbwg7ZWcIOyFiOydtOqzoCBsZW5ndGjtlajsiJjsl5DshJzrj4Qg66eI7LCs6rCA7KeA66GcIHRoaXPripQgb2Jq6rCAIOuQmOqyjOuQnOuLpAogICAgICBjb25zb2xlLmxvZygn64Sk7J207Yuw67iM7JeQIOq1rO2YhOuQnCBBcnJheS5wcm90b3R5cGUuam9pbu2VqOyImOyXkCDsnZjtlbQg7Zi47Lac65CY7JeI64ukJyk7CiAgICAgIFsuLi50aGlzLnN0cl0uZm9yRWFjaCgoYywgaSkgPT4gdGhpc1tpXSA9IGMpCiAgICAgIHJldHVybiB0aGlzLnN0ci5sZW5ndGg7CiAgIH0KfTsKY29uc29sZS5sb2cob2JqLnN1bSgnLycpKQovLyBvYmouc3Vt7JeQIEFycmF5LnByb3RvdHlwZS5qb2lu7ZWo7IiY66W8IOuLtOyVmOuLpAovLyBBcnJheS5wcm90b3R5cGUuam9pbiDtlajsiJjripQg64K07J6l7ZWo7IiY7J2066+A66GcIOuCtOu2gCDqtaztmITsnYQg64iI7Jy866GcIO2ZleyduO2VtOuztOq4sOuKlCDslrTroLXsp4Drp4wg64K067aA7KCB7Jy866GcIHRoaXPqsIAg7IKs7Jqp65CY6rOg7J6I7J2E6rKD7J206rOgIHRoaXPrpbwg7Yag64yA66GcIOyDiOuhnOyatCDqsJLsnYQg66eM65Ok7Ja064K064qUIOyXre2VoOydhCDtlZzri6QKLy8gWydhJywnYicsJ2MnXS5qb2luKCcvJykg7J2EIOyImO2Wie2VmOuptCAuam9pbiDslZ7snZggWydhJywnYicsJ2MnXSDqsIAgam9pbiDtlajsiJgg7JWI7JeQ7IScIHRoaXPqsIAg65Cg6rKD7J206rOgIOyduOyekOuhnCDrsJvsnYAgLyDrpbwg67Cw7Je07J2YIOyalOyGjOyalOyGjCDsgqzsnbTsl5Ag64Sj7Ja0IOusuOyekOyXtOuhnCDsnbTslrTrtpnsnbgg6rCS7J2EIOumrO2EtO2VtOyjvOuKlCDsl63tlaDsnYQg7ZWc64ukCi8vIOq3uOufsCDsl63tlaDsnYQg7ZWY64qUIO2VqOyImOulvCDrgrTqsIAg66eM65OgIG9iauudvOuKlCDqsJ3ssrTrpbwgdGhpc+uhnCDsgrzslYTshJwg7J6R64+Z7ZWY64+E66GdIOunjOuTpOyWtOuzuCDsvZTrk5zsnbTri6QKLy8gb2JqLnN1bSgnLycpIOydtOugh+qyjCDsi6Ttlonsi5wgc3VtIO2VqOyImCDslYjsl5DshJwgdGhpcyDripQgb2JqIOqwgCDrkJjqs6Agb2JqLmxlbmd0aOqwkuydhCDssLjsobDtlZjsl6wg6rCS7J2EIOykgOu5hO2VtOuCtOuKlCDqsoPsnYQg7ZmV7J24IO2VoCDsiJgg7J6I64ukCi8vIGxlbmd0aOqwgCDsl4bsnYQg6rK97JqwIOygleyDgeyekeuPmeuQmOyngCDslYrsnYzsnYQg7ZmV7J24IO2VoCDsiJgg7J6I64ukCi8vIGpvaW7snZgg64K067aA6rWs7ZiE7J2EIOuIiOycvOuhnCDtmZXsnbjtlZzqsoPsnYAg7JWE64uI7KeA66eMIGxlbmd0aOqwgCDsl4bsnYQg6rK97JqwIOygleyDgeyekeuPmSDtlZjsp4Ag7JWK64qU6rKD7Jy866GcIOuvuOujqOyWtOuzvOuVjCBqb2luIOydgCB0aGlzLmxlbmd0aOulvCDtmZXsnbjtlZjqs6Ag7J6I7J2E6rKD7J6E7J2EIOyDneqwgSDtlaAg7IiYIOyeiOuLpAovLyB0aGlzLmxlbmd0aOyXkCDsoJHqt7ztlZjqs6DsnojsnYzsnYAgbGVuZ3Ro66W8IGdldHRlcu2VqOyImOuhnCDqtaztmITtlbTrkZDslrQg6re46rKD7J2EIOymneuqhe2VmOyYgOuLpA==
// this를 알아보자 // 이거 안어렵다 // 이 글에서는 안어렵게 할거다 // 이 글 보기전에 일단 객체랑 함수의 기본은 알아야한다 // 모르면 먼저 객체랑 함수사용방법 먼저 알고 오자 let object = { method: function () { console.log('Hello') }, arrow: () => { console.log('Arrow') } } // 이렇게 객체를 만들고 method속성에 함수를 담을 수 있다 // arrow속성에도 함수를 담았다 // 함수모습이 두개가 다르다. // 그래도 일단 둘다 함수다 // ()=>{} 이건 화살표함수라고 한다 object.method object.arrow // 이렇게 접근할 수 있다 // 이것은 함수이다 // 함수 뒤에 () 를 붙이면 실행할 수 있다 object.method() object.arrow() // 실행했다 // 실행하면 각각 Hello랑 Arrow가 콘솔에 찍힌다 let object2 = { method: function () { console.log(this) }, arrow: () => { console.log(this) } } // Hello랑 Arrow대신에 this라는걸 넣어보자 object2.method() object2.arrow() // object2.method() 를 실행했을때는 .method() 앞에 있는 object2가 this가 된다 // object2.arrow() 를 실행했을때는 .arrow() 앞에 있는 object2가 this가 되는것이 아니다 // 그럼 object2.arrow() 를 실행했을때는 this는 어떻게 되는거지..? 에 대한 이야기는 잠시 뒤로하자 function method() { console.log(this.val); } let obj1 = { method: method, val: 1 }; let obj2 = { method: method, val: 2 }; // 자 이렇게 코드를 준비해봤다 // obj1, obj2 객체에 담아준 method는 결국 같은 함수를 의미한다 console.log(obj1.method === obj2.method) // 같다 obj1.method(); obj2.method(); // 그렇다면 이렇게 하면 실행하는 함수가 같다는 뜻이다 // method 함수를 실행하면 this.val 을 콘솔에 찍게 되어있다 // 그런데 결과를 보면 각각 다른 값이 찍혀있는것이 확인된다 // 같은 함수를 실행했는데 결과가 다르다 // 이런 차이를 만든것은 어떻게 실행했는지에 의해 정해진것이다 // .method() 앞에 무엇이 왔는지에 의해서 this가 결정된것이다 function hello() { console.log('hello') } function hello2() { console.log('hello2') } function hello3() { this(); } hello.method = hello3; hello2.method = hello3; hello.method() hello2.method() // 이것도 같은 이야기다 // 함수라하더라도 함수도 객체이므로 hello.method 와 같은 식으로 속성를 만들어줄수있다 // 이 속성에 함수를 담았고 위와같은 방법으로 실행했다 // hello.method() 이렇게 실행시 method 함수 즉 hello3함수에서의 this는 실행해주는 시점에 .method() 앞에 있는것이 된다 // 즉 this는 hello가 된다. hello는 함수이므로 this() 의 방법으로 함수를 실행할 수 있는것이다 let obj3 = { method: function () { let obj4 = { method2: () => { return this; } }; return obj4.method2(); } } console.log(obj3.method() === obj3); // 뒤로 미뤄뒀던 화살표함수를 보자 // 이 코드는 true가 나온다 // obj3.method() 를 실행하게되면 .method() 앞에 obj3이 method 함수 안에서 this가 된다 // method 함수 안에서는 또 obj4.method2() 이런식의 코드가 실행되게 되는데 이때 method2 함수 안에서 this는 함수 실행코드에서 .method2() 앞의 obj4를 의미하게 되지않는다 // 그런 이유는 method2는 화살표 함수이기 때문이다. 그러면 this는 무엇이 되는가 obj3이 된다 // 지금까지의 결과를 보면 this는 this를 포함한 함수가 어떤식으로 실행되느냐에 따라 그 의미가 정해지는것을 확인했다 // 아래의 코드는 좀 복잡할수도 있으니 그냥 가볍게 보자. // 이해를 꼭 하지 않아도 된다 let obj = { str: 'hello', sum: Array.prototype.join, get length() { // obj.sum('/') 해서 실행시 // 세군데의 this는 obj가 된다 // join함수에서는 this.length로 접근하고 있을것이라는것 짐작할 수 있다 // this는 obj이므로 obj.length를 한 셈이고 length함수에서도 마찬가지로 this는 obj가 되게된다 console.log('네이티브에 구현된 Array.prototype.join함수에 의해 호출되었다'); [...this.str].forEach((c, i) => this[i] = c) return this.str.length; } }; console.log(obj.sum('/')) // obj.sum에 Array.prototype.join함수를 담았다 // Array.prototype.join 함수는 내장함수이므로 내부 구현을 눈으로 확인해보기는 어렵지만 내부적으로 this가 사용되고있을것이고 this를 토대로 새로운 값을 만들어내는 역할을 한다 // ['a','b','c'].join('/') 을 수행하면 .join 앞의 ['a','b','c'] 가 join 함수 안에서 this가 될것이고 인자로 받은 / 를 배열의 요소요소 사이에 넣어 문자열로 이어붙인 값을 리턴해주는 역할을 한다 // 그런 역할을 하는 함수를 내가 만든 obj라는 객체를 this로 삼아서 작동하도록 만들어본 코드이다 // obj.sum('/') 이렇게 실행시 sum 함수 안에서 this 는 obj 가 되고 obj.length값을 참조하여 값을 준비해내는 것을 확인 할 수 있다 // length가 없을 경우 정상작동되지 않음을 확인 할 수 있다 // join의 내부구현을 눈으로 확인한것은 아니지만 length가 없을 경우 정상작동 하지 않는것으로 미루어볼때 join 은 this.length를 확인하고 있을것임을 생각 할 수 있다 // this.length에 접근하고있음은 length를 getter함수로 구현해두어 그것을 증명하였다