Closure

閉包 (closure)

  • closure 最常見的方式,就是直接回傳 function。
  • 在傳回一整個函數時,可以順便把外層的變數給包進來。

範例一

var myObject = function(){
  var value = 0;

  return {
    increment: function(inc){
      value += inc;
    },
    getValue: function(){
      return value;
    }
  }
}

var counter = myObject();
counter.increment(1);
counter.increment(1);
counter.getValue();

範例二

// 錯誤示範
function buildFunctions() {
  var arr = [];
  for (var i = 0; i < 3; i++) {
    // create phase
    arr.push(
      function() {
        console.log(i);
      }
    )
  }
  return arr;
}

var fs = buildFunctions();

// involve phase
fs[0]();
fs[1]();
fs[2]();
function buildFunctions2() {
  var arr = [];
  for (var i = 0; i < 3; i++) {
    // llfe & closure
    arr.push(
      (function(j) {
        return function() {
          console.log(j);
        }
      }(i))
    )
  }
  return arr;
}

var fs2 = buildFunctions2();

fs2[0]();
fs2[1]();
fs2[2]();

範例三

function makeGreeting(language) {
  return function(firstname, lastname) {
    if (language === 'en') {
      console.log('Hello ' + firstname + ' ' + lastname);
    }
    if (language === 'es') {
      console.log('Hola ' + firstname + ' ' + lastname);
    }
  }
}

var greetEnglish = makeGreeting('en');
var greetSpanish = makeGreeting('es');

greetEnglish('John', 'Doe');
greetSpanish('John', 'Doe');

範例四

function greet() {
  var greeting = 'Hi';
  setTimeout(function() {
    console.log(greeting);
  }, 3000);
}

greet();

範例五

var person = (function() {
  // var self = this;
  var nickname = 'alincode';

  function a() {
    console.log('hi', nickname);
  }

  function b() {
    console.log('eat', nickname);
  }

  function c() {
    console.log('OMG', nickname);
  }

  return {
    a: a,
    b: b,
    reset: function() {
      nickname = 'alin';
      // dont do that...
      // self.nickname = 'alin';
      // dont do that...
      // this.nickname = 'alin';
    }
  };
})();

person.a();
person.b();
person.reset();
person.a();

results for ""

    No results matching ""