一等公民(First Class Citizens)

  • 函数可以赋值给变量 var stuff = function() {}

  • 函数作为函数形参

  • 函数作为函数的返回值

闭包的解释

🧑🏻‍💻 A closure is when an outer function returns an inner function, the inner function is then executed in a different scope, and the inner function continues to maintain access to the outer function's variables, even though the outer function no longer exists.

function callMeMaybe() {
	setTimeout(function() {
		console.log(calMe);
	}, 4000);
	const callMe = 'Hi! I am now here!';
}
function compute(type, a, b) {
	compute.plus = function(a,b) {
        return a+b;
    }
    compute.minus = function(a,b) {
        return a-b;
    }
    compute.div = function(a,b) {
        return a/b;
    }
    compute.mul = function(a,b) {
        return a*b;
    }
    return compute[type](a,b);
}

闭包的好处

heavyDuty 每调用一次就会打印一次, getHeavyDuty 只会调用一次

function heavyDuty(item) {
  const bigArray = new Array(7000).fill('😄')
  console.log('created!');
  return bigArray[item]
}
 
heavyDuty(699)
heavyDuty(699)
heavyDuty(699)
const getHeavyDuty = heavyDuty2();
getHeavyDuty(699)
getHeavyDuty(699)
getHeavyDuty(699)
 
// but i dont want to pollute the global namespace..
function heavyDuty2() {
  const bigArray = new Array(7000).fill('😄')
  console.log('created Again!')
  return function(item) {
    return bigArray[item]
  }
}

闭包模拟私有化(encapsulation)

  • 两种写法(仅仅对外暴露出方法,外部无法访问其变量)
var Compute = (function () {
    var a = 100;
 
    class Compute {
        add(b) {
            return a + b;
        }
    }
    return Compute;
})();
 
var c = new Compute();
console.log(c.a);       // undefined
console.log(c.add(200)) //300
;(function () {
    var a = 100;
 
    function Compute() {};
    Compute.prototype.add = function(b) {
      return a + b;
    }
    
    window.Compute = Compute;
})();
 
var c = new Compute();
console.log(c.a);       // undefined
console.log(c.add(200)) //300
  • 内部用关键字定义变量
function Comput() {
  var a = 100;
  this.add = function(b) {
    return a+b;
  }
}
var c = new Comput();
console.log(c.a);//undefined
function Comput() {
  this.a = 100;
  this.add = function(b) {
    return a+b;
  }
}
var c = new Comput();
console.log(c.a);//100

Example: Using a Closure in an init function to ensure that the function is only executed once

const init = () => {
  let initialized = false;
 
  return () => {
    if (initialized) {
      return console.warn('⚠️ init function already called, not initializing');
    }
 
    initialized = true;
    return console.info('initialized 🚀');
	 };
};
const initialize = init();
 
initialize();
initialize();
initialize();

Reference

Javascript Closures Made Easy