사용자 도구

사이트 도구


study:ecma2015

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

study:ecma2015 [2024/01/27 05:51] – [ECMA2015(ES6)] taekgustudy:ecma2015 [2025/04/15 10:05] (현재) – 바깥 편집 127.0.0.1
줄 1: 줄 1:
 +
 +====== ECMA2015(ES6) ======
 +[[book:ecmascript:home|JavaScript Mama’s book]]
 +
 +  * [[http://www.ecma-international.org/publications/standards/Ecma-262.htm|Standard ECMA-262 최신 ES2022 - 2019]]
 +  * [[https://developer.mozilla.org/ko/docs/Web/JavaScript|JavaScript MDN]]
 +  * [[javascript:vanilla|Vanilla Javascript]]
 +  * [[http://daplus.net/javascript-javascript%EC%97%90%EC%84%9C-dom-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EB%B0%94%EC%9D%B8%EB%94%A9%EC%9D%84-%EA%B5%AC%ED%98%84%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95/|재미있는 2-Way 데이터 바인딩]]
 +  * [[https://javascriptpi.blogspot.com/2016/12/two-way-data-binding.html|DOM 요소를 서로 또는 JavaScript 객체와 바인딩하는 방법을 보여주는 코드와 데모입니다.]]
 +  * [[https://rxjs.dev/|rxjs - Angular에서 사용하는 two way data binding 라이브러리]]
 +  * [[https://poiemaweb.com|웹 프로그램 튜토리얼(정리잘되어있음)]]
 +  * [[javascript:bootstrap|Javascript BootStrap]]
 +  * [[javascript:handbook|Javascript 요약집]]
 +  * [[javascript:clone|Clone Function]]
 +  * [[javascript:regexp|regexp예]]
 +  * [[javascript:maro_pattern|Maro Pattern]]
 +  * avgrund - popup jQuery lib
 +
 +  * [[http://webframeworks.kr/tutorials/translate/arrow-function/|화살표 함수와 메소드 정의]]
 +  * [[javascript:browser|edge로 가기]]
 +  * DevTool열기<code>
 +`Control+Shift+J`
 +`Command+Option+J`(Mac의 경우)를
 + 눌러 DevTools를 엽니다.
 +</code>
 +  
 +===== Netscape --javascript(JAVA ..) =====
 +
 +  - prototype
 +  - jquery
 +  - React - facebook 서비스(라이브리성...)
 +  - AngularJS - Angular1.0 - Google -- javascript
 +  - Vue
 +  - Angular 2 --> Angular -- typescript
 + 
 +
 +
 +
 +  * [[javascript:array|Array]]
 +  * [[javascript:extend|Object extend]]
 +  * [[javascript:regexp|RegExp 전화번호]]
 +  * [[javascript:regexp|RegExp Password]]
 +  * [[javascript:class|Class와 this]]
 +  * [[javascript:callbackAndThis|callback function과 this]]
 +  * [[javascript:void|void undefined]]
 +===== ECMAScript 2015 =====
 +
 +
 +ES6 === ES2015
 +(ES2016,ES2017..)
 +ES2015
 +개선된 JavaScript문법\\
 +ES6 browser compatibility의 훌륭한 지원.\\
 +ES6를 기반으로 한 JavaScript생태계의 확산.\\
 +[[https://kangax.github.io/compat-table/es6/|브라우저 호환성]]
 +==== language 기본 ====
 +  * var
 +    * function scope
 +  * let
 +    * block scope like for a general programming language
 +  * const
 +    * 재할당을 하지 못한다.
 +    * 배열의 push등은 가능하다.
 +    * immutable array를 만들어서 사용할 수 있다.
 +      * <code javascript>
 +        const list = ["apple","orange","watermelon"];
 +        const list2 = [].concat(list, "banana");
 +        console.log(list2);
 +        console.log(list === list2);
 +        </code>
 +  * string에 추가 method
 +    * startsWith
 +    * endsWith
 +    * includes
 +  * for of - 순회하기
 +    * <code javascript>
 +var data = [1,2,234];
 +data.forEach(function(value,idx){
 +  console.log(value);
 +});
 +
 +data.forEach(function(value){
 +  console.log(data[a]);
 +}
 +for(let idx in data) {
 +  console.log(data[idx]);
 +}
 +Array.prototype.getIndex = function(){} 
 +// for in 에서 문제발생
 +// Object의 function도 같이 순회한다.
 +
 +for(let value of data) {
 +  console.log(value);
 +}
 +
 +let str = 'asdf 111';
 +for(let value of str) { // character단위로 순회한다.
 +  console.log(value);
 +}
 +</code>
 +
 +  * || ?? operator
 +    * <code>let height = 0;
 +
 +alert(height || 100); // 100
 +alert(height ?? 100); // 0
 +</code>
 +  * spread operator, 펼침연산자
 +    * <code javascript>
 +let pre = ["apple","orange", 100];
 +let newData = [...pre];
 +console.log(pre === newData);
 +</code>
 +    * <code javascript>
 +let pre=[100,200,"hello",null];
 +
 +let newData = [0,1,2,3, ...pre, 4];
 +</code>
 +    * Argument로 넘겨 줌 <code javascript>
 +function sum(a,b,c){
 +  return a+b+c;
 +}
 +let pre = [100,200,300];
 +console.log(sum.apply(null, pre));
 +
 +console.log(sum(...pre));
 +</code>
 +
 +=== ES2015 from method ===
 +
 +<code javascript>
 +function addMark(){
 +  let newData = [];
 +  
 +  for(let i=0; i < arguments.length; i++) {
 +    newData.push(arguments[i] + "!");
 +  }
 +  
 +  console.log(newData);
 +}
 +
 +addMark(1,2,3,4,5);
 +</code>
 +argument.map활용 --> Error남... 배열같지만 배열이 아닌 것들이 javascript에는 존재한다.
 +<code javascript>
 +function addMark(){
 +  //let newData = arguments.map(function(value){ //--> Error
 +  let newarray = Array.from(arguments);
 +  let newData = newarray.map(function(value){
 +    return value + "!";
 +  });
 +  
 +  console.log(newData);
 +}
 +
 +addMark(1,2,3,4,5);
 +</code>
 +
 +==== 예제1 ====
 +<code html ex1.html>
 +<!DOCTYPE html>
 +<html>
 +<head>
 +  <meta charset="utf-8">
 +  <meta name="viewport" content="wid">
 +  <title>JS Bin</title>
 +</head>
 +<body>
 +  <ul>
 +    <li>apple</li>
 +    <li>orange</li>
 +    <li>banana</li>
 +    <li>strawberry</li>
 +  </ul>
 +</body>
 +</html>
 +</code>
 +
 +=== 문제 ===
 +<code javascript ex1.js>
 +function print() {
 +  /*
 +  filter, includes, from을 사용해서 문자열'e'가 포함된
 +  노드로 구성된 배열을 만들어서 반환하기
 +  */
 +}
 +
 +print();
 +</code>
 +
 +=== 풀이 ===
 +<code javascript aw1.js>
 +function print() {
 +  /*
 +  filter, includes, from을 사용해서 문자열'e'가 포함된
 +  노드로 구성된 배열을 만들어서 반환하기
 +  */
 +  let list = document.querySelectorAll("li");
 +  console.log(toString.call(list));
 +  
 +  let listArray = Array.from(list);
 +  console.log(toString.call(listArray));
 +  
 +  let eArray = listArray.filter(function(v){
 +    //return v.includes("e"); // Error . v는 node
 +    return v.innerText.includes("e");//
 +  });
 +  return eArray;
 +}
 +
 +console.log(print());
 +</code>
 +
 +==== Object ====
 +function을 이용한 Object생성
 +<code javascript>
 +function getObj(){
 +  const name = "crong";
 +  
 +  const getName = function() {
 +    return name;
 +  }
 +  
 +  const setName = function(newName) {
 +    name = newName;
 +  }
 +  
 +  const printName = function() {
 +    console.log(name);
 +  }
 +  
 +//  return {
 +//    getName: getName,
 +//    setName: setName
 +//  }
 +  return { getName, setName }
 +}
 +
 +var obj = getObj();
 +console.log(obj.getName());
 +</code>
 +
 +==== Destructuring ====
 +
 +=== Array ====
 +<code javascript>
 +let data = ["crong","honux","jk","jinny"];
 +let [jisu,,jung] = data;
 +console.log(jisu, jung);
 +</code>
 +
 +=== Object ===
 +<code javascript>
 +let obj = {
 +  name : "crong",
 +  address : "korea",
 +  age : 10
 +}
 +obj["name"];
 +obj.name;
 +;
 +
 +obj = $.extend(obj,
 +{
 +name2 : "asdfa";
 +}
 +)
 +obj["name"];
 +obj["name2"];
 +obj.name2;
 +
 +
 +let {name:myName, age:myAge} = obj; // myName, myAge변수에 할당함.
 +console.log(myName, myAge);
 +</code>
 +
 +=== 활용 JSON파싱 ===
 +<code javascript>
 +var news = [
 +  { "title":"sbs",
 +    "imgurl":"http://asdfasdf",
 +    "newslist":[
 +    ]
 +  },
 +  { "title":"mbc",
 +    "imgurl":"http://asdfasdf",
 +    "newslist":[
 +    ]
 +  }
 +];
 +
 +let [,mbc] = news;
 +let {title, imgurl} = mbc;
 +console.log(title,imgurl);
 +
 +</code>
 +
 +<code javascript>
 +let [,{title,imgurl}] = news;
 +console.log(title,imgurl);
 +</code>
 +
 +<code javascript>
 +function getNewsList([,newslist]){
 +  console.log(newslist);
 +}
 +getNewsList(news);
 +</code>
 +
 +=== Event ===
 +<code javascript>
 +document.querySelector("div").addEventListener("click",fucntion(evt){
 +  console.log(evt);
 +});
 +document.querySelector("div").addEventListener("click",fucntion({target}){
 +  console.log(target.tagName);
 +});
 +document.querySelector("div").addEventListener("click",fucntion({type}){
 +  console.log(type);
 +});
 +</code>
 +
 +==== SET ====
 +자료구조 Set - 중복없이 유일한 값을 저장하려고 할때, 이미 존재하는지 체크할 때 유용.
 +<code javascript>
 +let mySet = new Set();
 +console.log(toString.call(mySet));
 +
 +mySet.add("crong");
 +mySet.add("hary");
 +mySet.add("chrong");
 +
 +console.log(mySet.has("crong"));
 +
 +mySet.forEach(function(v){
 +  console.log(v);
 +});
 +
 +
 +mySet.delete("crong");// set에서 삭제
 +</code>
 +
 +=== WeakSet ===
 +참조를 가지고 있는 객체만 지정이 가능하다.
 +객체형태를 중복없이 저장하려고 할때 유용하다.
 +<code javascript>
 +let arr = [1,2,3,4];
 +let ws = new WeekSet();
 +
 +ws.add(arr);
 +ws.add(111); // error
 +ws.add("111"); // error
 +ws.add(null); // error
 +ws.add(fuction(){});
 +console.log(ws);
 +</code>
 +
 +<code javascript>
 +let arr = [1,2,3,4];
 +let arr2 = [5,6,7,8];
 +let obj = {arr, arr2};
 +let ws = new WeekSet();
 +
 +ws.add(arr);
 +ws.add(arr2);
 +ws.add(obj);
 +
 +arr = null;
 +arr2 = null;
 +console.log(ws);
 +console.log(ws.has(arr), ws.has(arr2));
 +</code>
 +==== map & WeakMap ====
 +Array --> set,weakset
 +Object --> map, weakmap
 +
 +map은 key/value의 구조(dictionary)
 +
 +<code javascript>
 +let wm = new WeakMap();
 +let myfun = function(){};
 +// 이 함수가 얼마나 실행됐는지를 알려고 할때
 +
 +wm.set(myfun,0);
 +
 +console.log(wm);
 +
 +let count = 0;
 +for(let i=0;i<10;i++){
 +  count = wm.get(myfun); // get value
 +  count++;
 +  wm.set(myfun, count);
 +}
 +
 +console.log(wm.get(myfun)); // 10
 +</code>
 +
 +
 +<code javascript>
 +myfun = null;
 +console.log(wm.get(myfun)); // undefined
 +
 +console.log(wm.has(myfun)); // false
 +
 +</code>
 +
 +=== WeakMap 활용 --> private ===
 +<code javascript>
 +function Area(height, width){
 +  this.height = height;
 +  this.width = width;
 +}
 +
 +Area.prototype.getArea = function(){
 +  return this.height * this.width;
 +}
 +
 +lget myarea = new Area(10,20);
 +console.log(myarea.getArea());
 +console.log(myarea.height);
 +</code>
 +
 +=== weakmap의 전역변수를 이용 ===
 +<code javascript>
 +const wm = new WeakMap();
 +function Area(height,width){
 + wm.set(this, {height, width});
 +}
 +
 +Area.prototype.getArea = function(){
 +  const {height, width} = wm.get(this);
 +  return height * width;
 +}
 +lget myarea = new Area(10,20);
 +console.log(myarea.getArea());
 +console.log(myarea.height);
 +
 +
 +//
 +
 +console.log(wm.has(myarea));// true;
 +myarea = null;
 +console.log(wm.has(myarea));// false;
 +// Garbage Collection
 +</code>
 +
 +==== 실습.Destructuring and Set 활용 ====
 +=== lotto번호만들기. ===
 +  - 유일한값을 추출하는 과정에서 Set을 사용합니다.
 +  - getRandomNumber함수에 변수를 전달하는 과정에서 destructuring을 사용해봅시다.
 +<code javascript>
 +const SETTING = {
 +  name : "LUCKY LOTTO!",
 +  count : 6,
 +  maxNumber : 45
 +}
 +
 +function getRandomNumber(maxNumber) {
 +// 랜덤한 유일한 숫자값을 추출
 +}
 +</code>
 +=== Answer ===
 +
 +<code javascript>
 +const SETTING = {
 +  name : "LUCKY LOTTO!",
 +  count : 6,
 +  maxNumber : 45
 +}
 +
 +function getRandomNumber(maxNumber) {
 +// 랜덤한 유일한 숫자값을 추출
 +}
 +</code>
 +
 +==== Template처리 ====
 +json으로 응답을 받고,
 +javascript object로 변환한 후에 어떠한 데이터처리 조작을 한 후에 dom에 추가!
 +데이터 + HTML문자열의 결합이 필요하기 때문에
 +
 +<code javascript>
 +const data = [
 +  {
 +    name : 'coffee-bean',
 +    order : true,
 +    items : ['americano', 'milk', 'green-tea']
 +  },
 +  {
 +    name : 'starbucks',
 +    order : false,
 +  }
 +];
 +
 +const template = `<div>welcome ${data[0].name} !!</div>`
 +console.log(template);
 +</code>
 +
 +=== Tagged template literals ===
 +
 +<code javascript>
 +const data = [
 +  {
 +    name : 'coffee-bean',
 +    order : true,
 +    items : ['americano', 'milk', 'green-tea']
 +  },
 +  {
 +    name : 'starbucks',
 +    order : false,
 +  }
 +];
 +// Tagged template literals
 +function fn(tags, name, items) {
 +  //console.log(tags);
 +  if(typeof items === "undefined") {
 +    items = "주문가능한 상품이 없습니다.";
 +  }
 +  return (tags[0] + name + tags[1] + items + tags[2]);
 +}
 +const template = fn`<div>welcome ${data[0].name}!!</div>
 +  <h2>주문가능항목</h2><div>${data[0].items}</div>`;
 + 
 +//console.log(template);
 +
 +data.forEach(v => {
 +  let template = fn`<div>welcome ${v.name}!!</div>
 +  <h2>주문가능항목</h2><div>${v.items}</div>`;
 +  console.log(template);
 +  document.querySelector('#message').innerHTML += template;
 +});
 +</code>
 +
 +==== Arrow Function ====
 +
 +<code javascript>
 +setTimeout(function(){
 +  console.log("settimeout");
 +}, 1000);
 +
 +let newArr = [1,2,3,4,5].map(function(value, index, object) {
 +  return value * 2;
 +});
 +
 +let newArr3 = [1,2,3,4,5].map( (v) => (v * 3));
 +let newArr4 = [1,2,3,4,5].map( v => v * 4);
 +</code>
 +
 +=== this context of Arrow function ===
 +<code javascript>
 +
 +const myObj = {
 +  runTimeout() {
 +    setTimeout(function(){
 +      this.printData(); // this는 window( in browser).
 +                        // bind(this)를 통해서 myObj로 bind
 +    }.bind(this), 200);  
 +  },
 +  printData(){
 +    console.log('hi codesquad!');
 +  }
 +}
 +
 +myObj.runTimeout();
 +</code>
 +== arrow function에서 this ==
 +<code javascript>
 +const myObj = {
 +  runTimeout() {
 +    setTimeout(()=>{
 +      this.printData();
 +    }, 200);
 +  },
 +  printData(){
 +    console.log('hi codesquad!');
 +  }
 +}
 +
 +myObj.runTimeout();
 +</code>
 +== DOM Event도 같은 방식 ==
 +<code javascript>
 +const el = document.querySelector("p");
 +
 +const myObj = {
 +  register() {
 +    el.addEventListener("click", (evt) => {
 +      this.printData(evt.target); // bind없이 this
 +    });
 +  },
 +  
 +  printData(el) {
 +    console.log('clicked!!', el.innerText);
 +  }
 +}
 +myObj.register();
 +</code>
 +
 +==== default parameters ====
 +<code javascript>
 +function sum(value, size=1){
 +  return value * size;
 +}
 +
 +console.log(sum(3));
 +</code>
 +
 +=== object ===
 +<code javascript>
 +function sum(value, size={value:1}){
 +  return value * size.value;
 +}
 +
 +console.log(3, {value:0}));
 +</code>
 +
 +==== rest parameters ====
 +<code javascript>
 +function checkNum(){
 +  const argArray = Array.prototype.slice.call(arguments);
 +  console.log(argArray);
 +  console.log(toString.call(arguments));
 +  const result = argArray.every((v) => typeof v === "number");
 +  console.log(result);
 +}
 +
 +const result = checkNum(10,2,3,"55");
 +const result = checkNum(10,2,3,4,5,"55");
 +</code>
 +
 +rest parameters
 +<code javascript>
 +function checkNum(...argArray){
 +  const result = argArray.every((v) => typeof v === "number");
 +  console.log(result);
 +}
 +</code>
 +
 +===== ES6 class =====
 +<code javascript>
 +function Health(name){
 +  this.name = name;
 +}
 +
 +Health.prototype.showHealth = function(){
 +  console.log(this.name + "님 안녕하세요");
 +}
 +</code>
 +
 +==== constructor ====
 +<code javascript>
 +class Health {
 +  constructor(name, lastTime) {
 +    this.name = name;
 +    this.lastTime = lastTime;
 +  }
 +  showHealth() {
 +    console.log("안녕하세요" + this.name);
 +  }
 +}
 +
 +const myHealth = new Health("crong");
 +</code>
 +
 +==== Object assign 메서드 ====
 +ES5에 추가됨
 +<code javascript>
 +const healthObj = {
 +  showHealth : function() {
 +    console.log("오늘은 운동시간 : " + this.healthTime);
 +  }
 +}
 +
 +const myHealth = Object.create(healthObj);
 +
 +myHealth.healthTime = "11:20";
 +myHealth.name = "mama";
 +
 +console.log(myHealth);
 +</code>
 +
 +=== Object Assign ===
 +<code javascript>
 +const healthObj = {
 +  showHealth : function() {
 +    console.log("오늘은 운동시간 : " + this.healthTime);
 +  }
 +}
 +
 +const myHealth = Object.assign(Object.create(healthObj),{
 +  name : "mama",
 +  lastTime : "11:20"
 +});
 +
 +myHealth.healthTime = "11:20";
 +myHealth.name = "mama";
 +
 +console.log(myHealth);
 +</code>
 +
 +=== Object assign으로 immutable객체 만들기 ===
 +<code javascript>
 +const previousObj = {
 +  name : "mama",
 +  lastTime : "11:20"
 +}
 +
 +const myHealth = Object.assign({}, previousObj, {
 +  "lastTime" : "12:30"
 +});
 +
 +console.log("myhealth is ", myHealth);
 +</code>
 +
 +=== setPrototypeOf ===
 +명확하고 단순한 것을 유지함.
 +<code javascript>
 +const healthObj = {
 +  showHealth : function() {
 +    console.log("오늘 운동시간 : " + this.healthTime);
 +  }
 +}
 +const myHealth = {
 +  name : "mama",
 +  lastTime : "11:20"
 +}
 +
 +const newobj = Object.setPrototypeOf(myHealth, healthObj);
 +console.log("myhealth is ", myHealth);
 +
 +console.log("newobj is ", newobj);
 +</code>
 +
 +=== Object setPrototypeOf로 객체간 prototype chain생성하기 ===
 +<code javascript>
 +//parent
 +const healthObj = {
 +  showHealth : function() {
 +    console.log("오늘 운동시간 : " + this.healthTime);
 +  },
 +  setHealth : function(newTime) {
 +    this.healthTime = newTime;
 +  }
 +}
 +
 +// child obj
 +const healthChildObj = {
 +  getAge : function() {
 +    return this.age;
 +  }
 +}
 +
 +const lastHealthObj = Object.setPrototypeOf(healthChildObj, healthObj);
 +
 +const childObj = Object.setPrototypeOf({
 +  age: 22
 +}, healthChildObj);
 +
 +console.log("childObj is ", childObj);
 +</code>
 +==== Module(export & import)의 이해 ====
 +
 +아직은 Browser 에서는 사용 못 하고 있음.
 +
 +<code javascript app.js>
 +import log, { getTime, getCurrentHour } from './myLogger';
 +
 +log('my first test data');
 +log(`getTime is ${getTime()}`);
 +log(`current hour is ${getCurrentHour()}`);
 +</code>
 +
 +<code javascript myLogger.js>
 +export function log(data){
 +  console.log(data);
 +}
 +
 +export const getTime = () => {
 +  return Date.now();
 +}
 +
 +export const getCurrentHour = () => {
 +  return (new Date).getHours();
 +}
 +</code>
 +
 +==== Proxy ====
 +
 +<code javascript>
 +const myObj = { name:'mama', changedValue:0 };
 +const proxy = new Proxy(myObj, {
 +  get: function(target, property, receiver){
 +    console.log('get Value')
 +    
 +    // if(property in target) ... 없는 프러퍼티에 대해서 Error처리를 할 수 있다.
 +        
 +    //return target[property];
 +    return Reflect.get(target, property, receiver);
 +  },
 +  set: function(target, property, value, receiver){
 +    console.log('set value');
 +    console.log('target : ', target);
 +    console.log('value :', value);
 +    target['changedValue']++;
 +    target[property] = value;
 +    return true;
 +  }
 +});
 +
 +console.log('myObj : ', myObj);
 +console.log('proxy : ', proxy);
 +proxy.name = 'crong';
 +console.log('proxy : ', myObj);
 +</code>
 +===== 기타정보들 =====
 +==== IIFE[Immediately Invoked Function Expression] ====
 +“Iffy”라고 발음.
 +즉시호출함수표현...
 +기초 지식은 많이 있겠지만, JavaScript에서는 function도 하나의 data type 이다. 따라서 파라메터로 넘겨주는 것이 가능하다.
 +또한 JavaScript에서는 function의 이름을 생략할 수 있다.
 +<code javascript>
 +(function(d){
 +let myday = new Date(d);
 +myday.setFullYear(myday.getFullYear() + 1);
 +return myday;
 +})('2018.08.10');
 +</code>
 +
 +function f(a){
 +asdfasdfgo 일...
 +}
 +;
 +f('asdf');
 +
 +f(
 +(function(d){
 +let myday = new Date(d);
 +myday.setFullYear(myday.getFullYear() + 1);
 +return myday;
 +})('2018.08.10')
 +);
 +f('asd')
 +
 +==== About DATE ====
 +=== 날짜 포맷(yyyymmdd)출력하기(datepicker) ===
 +<code javascript>
 +(function(p_date){
 +  let startDate = new Date(p_date);
 +  startDate.setDate(startDate.getDate() + 1);
 +  return $.datepicker.formatDate('yy.mm.dd', startDate);
 +})("2018.09.12")
 +</code>
 +말일 구하기
 +<code javascript>(function(day){
 + let lastday = new Date(day.substring(0,4), day.substring(4,6)-1+1, 0);
 + return $.datepicker.formatDate('yymmdd', lastday);
 +})(getStdDate())
 +</code>
 +=== 날짜 더하기 ===
 +<code javascript>
 +((new Date()).getFullYear() + 1) + ".12.31"
 +</code>
 +
 +=== 요일명 ===
 +<code javascript>
 +var d = new Date()
 +d.toLocaleDateString('ko-KR', {weekday: 'long'})
 +</code>
 +==== 클로저(Closure) ====
 +=== jQuery에서 사용하는 클로저 ===
 +<code javascript>
 +$(function() {
 +  var selections = [];
 +  $(".niners").click(function() { // 이 클로저는 selections 변수에 접근합니다.
 +    selections.push(this.prop("name")); // 외부 함수의 selections 변수를 갱신함
 +    });
 +  });
 +</code>
 +
 +=== Private구현방법. ===
 +예제는 더글라스 크락포드(Douglas Crockford)에 의해 처음 시연되었습니다:
 +<code javascript>
 +function celebrityID() {
 +  var celebrityID = 999;
 +  // 우리는 몇개의 내부 함수를 가진 객체를 리턴할것입니다.
 +  // 모든 내부함수는 외부변수에 접근할 수 있습니다.
 +  return {
 +    getID: function() {
 +      // 이 내부함수는 갱신된 celebrityID변수를 리턴합니다.
 +      // 이것은 changeThdID함수가 값을 변경한 이후에도 celebrityID의 현재값을 리턴합니다.
 +      return celebrityID;
 +    },
 +    setID: function(theNewID) {
 +      // 이 내부함수는 외부함수의 값을 언제든지 변경할 것입니다.
 +      celebrityID = theNewID;
 +    }
 +  }
 +}
 +var mjID = celebrityID(); // 이 시점에, celebrityID외부 함수가 리턴됩니다.
 +mjID.getID(); // 999
 +mjID.setID(567); // 외부함수의 변수를 변경합니다.
 +mjID.getID(); // 567; 변경된 celebrityID변수를 리턴합니다.
 +</code>
 +
 +=== 비꼬기 ===
 +클로저가 갱신된 외부함수의 변수에 접근함으로써, 외부 함수의 변수가 for문에 의해 변경될 경우 의도치 않은 버그가 발생할 수 있습니다.
 +<code javascript>
 +function celebrityIDCreator(theCelebrities) {
 +  var i;
 +  var uniqueID = 100;
 +  for (i=0; i<theCelebrities.length; i++) {
 +    theCelebrities[i]["id"] = function() { return uniqueID + i; }
 +  }
 +  return theCelebrities;
 +}
 +
 +var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
 +var createIdForActionCelebs = celebrityIDCreator(actionCelebs);
 +var stalloneID = createIdForActionCelebs[0];
 +console.log(stalloneID.id); // 103
 +</code>
 +위의 예제에서, 익명의 내부함수가 실행될 시점에 i의 값은 3입니다(배열의 크기만큼 증가한 값). 숫자 3은 uniqueID에 더해져 모든 celebritiesID에 103을 할당합니다. 그래서, 기대(100,101,102)와 달리 모든 리턴된 배열의 id=103이 됩니다.
 +
 +이런 결과가 나타난 이유는, 앞서 언급했듯이 클로저는(이 예제에서 내부의 익명함수) 외부 변수에 대해 값이 아닌 참조로 접근하기 때문입니다. 즉, 클로저는 최종 갱신된 변수(i)에 대해서만 접근할 수 있으므로, 외부 함수가 전체 for문을 실행하고 리턴한 최종 i의 값을 리턴하게 됩니다. 100+3=103.
 +=== IIFE사용하여 수정하기 ===
 +이런 부작용을 고치기 위해서 “즉시 호출된 함수 표현식(Immediately Invoked Function Expression. IIFE)”를 사용할 수 있습니다.
 +<code javascript>
 +function celebrityIDCreator(theCelebrities) {
 +    var i;
 +    var uniqueID = 100;
 +    for (i=0; i<theCelebrities.length; i++) {
 +        theCelebrities[i]["id"] = function(j) {
 +            // j 파라미터는 호출시 즉시 넘겨받은(IIFE) i의 값이 됩니다.
 +            return function() {
 +                // for문이 순환할때마다 현재 i의 값을 넘겨주고, 배열에 저장합니다.
 +                return uniqueID + j;
 +            } () // 함수의 마지막에 ()를 추가함으로써 함수를 리턴하는 대신 함수를 즉시 실행하고 그 결과값을 리턴합니다.
 +        } (i); // i 변수를 파라미터로 즉시 함수를 호출합니다.
 +    }
 +    return theCelebrities;
 +}
 +var actionCelebs = [{name:"Stallone", id:0}, {name:"Cruise", id:0}, {name:"Willis", id:0}];
 +var createIdForActionCelebs = celebrityIDCreator(actionCelebs);
 +var stalloneID = createIdForActionCelebs[0];
 +console.log(stalloneID.id); // 100
 +var cruiseID = createIdForActionCelebs[1];
 +console.log(cruiseID.id); // 101
 +</code>
 +
 +==== 화살표함수와 this ====
 +ES5에서 가장 헷갈리는것이 바로 this의 범위이다. 클로저가 생성한 컨텍스트로 인해 this가 this가 아닌 상황이 발생하여 “that = this, self = this”와 같은 패턴을 사용해야만 했다.
 +<code javascript>
 +var self = this
 +$('.btn').click(function(event){
 +  self.sendData()
 +})
 +</code>
 +또는 “.bind(this)”를 사용해 this를 현재 컨텍스트와 수동으로 바인딩하기도 했었다.
 +<code javascript>
 +$('.btn').click(function(event){
 +  this.sendData()
 +}.bind(this))
 +</code>
 +화살표 함수를 사용하면 이러한 번거로움을 해소할 수 있다.
 +<code javascript>
 +$('.btn').click((event) =>{
 +  this.sendData()
 +})
 +</code>
 +화살표 함수는 함수 표현식을 간략하게 표기하도록도 해주지만 this의 범위를 함수를 감싸는 코드와 동일하게 유지해줌으로써 기존의 클로저로 인한 번거로움을 많이 해소해 준다.
 +
 +{{http://chanlee.github.io/categories/|ChanLee}}
 +