[코어 자바스크립트] 05. 클로져

jscn·2020년 9월 19일
1

Front-end

목록 보기
3/8

01. 클로져의 원리 및 의미 이해

클로저는 어떤 상황에서 발생하는 특수한 '현상' 함수는 이 현상이 나타나기 위한 '조건'에는 해당 하지만, 클로저 자체를 구체화한 '대상'으로 볼 수 없음.

클로저를 피부적으로 느껴지게 설명하면, "클로저 현상에 의해 메모리에 남겨진 변수들의 집합이다."

var outer = function(){
  var a=1;
  var inner=function(){
    return ++a;
  };
  return inner;
};

var outer2 = outer(); 
// inner 함수가 리턴됨: inner에서 참조하고있는 outer 함수의 lexicalEnvironment도 같이
console.log(outer2()); //2
console.log(outer2()); //3

02. 클로저와 메모리 관리

더이상 사용 되지 않는 다면 해당 객체에 null을 할당해서 함수 참조를 끊어 준다

: 참고 자료: https://itstory.tk/entry/자바스크립트에서-메모리-누수의-4가지-형태

03. 클로져 활용 사례

var fruits =['apple','banana', 'peach'];
var $ul = document.createElement('ul');

var alertFruit = function(fruit){
  alert('your choice is '+fruit) //[object MouseEvent]
}

fruits.forEach(function(fruit){
	var $li = document.createElement('li');
  $li.innerText = fruit;
  **$li.addEventListener('click',alertFruit);** 
  $ul.appendChild($li);
})

document.body.appendChild($ul);
alertFruit(fruits[1]);
var fruits =['apple','banana', 'peach'];
var $ul = document.createElement('ul');

var alertFruit = function(fruit){
  alert('your choice is '+fruit) //[object MouseEvent]
}

fruits.forEach(function(fruit){
	var $li = document.createElement('li');
  $li.innerText = fruit;
	**$li.addEventListener('click',alertFruit.bind(this, fruit)); //event 객체는 어떻게 넘김?**
  $ul.appendChild($li);
})

document.body.appendChild($ul);
alertFruit(fruits[1]);
var fruits =['apple','banana', 'peach'];
var $ul = document.createElement('ul');

var alertFruitBuilder = function(fruit){
 **return function(){
   console.log( fruit)  
//    alert('your choice is '+fruit)
 }**	
}

fruits.forEach(function(fruit){
	var $li = document.createElement('li');
  $li.innerText = fruit;
  **$li.addEventListener('click',alertFruitBuilder(fruit));**

  $ul.appendChild($li);
})

document.body.appendChild($ul);
alertFruit(fruits[1]);

예제 5-10 간단한 자동차 객체

var car = {
  fuel : Math.ceil(Math.random()*10+10),
  power: Math.ceil(Math.random()*3+2),
  moved: 0,
  run: function(){
    var km = Math.ceil(Math.random()*6)
    var wasteFuel =km/this.power;

    console.log(`fuel:${this.fuel}, power:${this.power}, moved:${this.moved}, km:${km}`)
    if(this.fuel<wasteFuel){
      console.log('cannot move')
      return;
    };
    this.fuel-=wasteFuel;
    this.moved+=km;
    console.log(`${km} km 이동 (총 ${this.moved}km). 남은 연료:${this.fuel}`)
  }
};

// var car =createCar();

console.log(car.moved);
console.log(car.fuel)
console.log(car.power)

console.log()
car.run();

console.log()
console.log(car.moved);
console.log(car.fuel)
console.log(car.power)
console.log(car)

console.log()
console.log('[TEST] car.fuel:1000')
car.fuel=1000;
console.log('>>',car.fuel)
car.run();

console.log()
console.log('[TEST] car.pw:100')
car.power=100;
console.log('>>',car.power)
car.run();

console.log()
console.log('[TEST] car.moved:1000')
car.moved=1000
console.log('>>',car.moved)
car.run();

예제 5-11 클로저로 변수를 보호한 자동차 객체(1)

var createCar = function(){
  var fuel = Math.ceil(Math.random()*10+10);
  var power = Math.ceil(Math.random()*3+2);
  var moved = 0;
  return{
    get moved(){
      return moved;
    },
    run: function(){

      var km = Math.ceil(Math.random()*6)
      var wasteFuel =km/power;

      console.log(`${fuel}, ${power}, ${moved}, ${km}`)
      if(fuel<wasteFuel){
        console.log('cannot move')
        return;
      };
      fuel-=wasteFuel;
      moved+=km;
      console.log(`${km} km 이동 (총 ${moved}km). 남은 연료:${fuel}`)
    }
  };
};

var car =createCar();

car.run();

console.log()
console.log(car.moved);
console.log(car.fuel)
console.log(car.power)
console.log(car)

console.log()
console.log('[TEST] car.fuel:1000')
car.fuel=1000;
console.log('>>',car.fuel)
car.run();

console.log()
console.log('[TEST] car.pw:100')
car.power=100;
console.log('>>',car.power)
car.run();

console.log()
console.log('[TEST] car.moved:1000')
car.moved=1000
console.log('>>',car.moved)
car.run();

예제 5-12 클로저로 변수를 보호한 자동차 객체(2)

var createCar = function(){
  var fuel = Math.ceil(Math.random()*10+10);
  var power = Math.ceil(Math.random()*3+2);
  var moved = 0;
  
  var publicMembers={
    get moved(){
      return moved;
    },
    run: function(){

      var km = Math.ceil(Math.random()*6)
      var wasteFuel =km/power;

      console.log(`${fuel}, ${power}, ${moved}, ${km}`)
      if(fuel<wasteFuel){
        console.log('cannot move')
        return;
      };
      fuel-=wasteFuel;
      moved+=km;
      console.log(`${km} km 이동 (총 ${moved}km). 남은 연료:${fuel}`)
    }
  }
	Object.freeze(publicMembers)
  return publicMembers
};

var car =createCar();

car.run();

console.log()
console.log(car.moved);
console.log(car.fuel)
console.log(car.power)
console.log(car)

console.log()
console.log('[TEST] car.fuel:1000')
car.fuel=1000;
console.log('>>',car.fuel)
car.run();

console.log()
console.log('[TEST] car.pw:100')
car.power=100;
console.log('>>',car.power)
car.run();

console.log()
console.log('[TEST] car.moved:1000')
car.moved=1000
console.log('>>',car.moved)
car.run();
profile
Frontend engineer

0개의 댓글