Skip to content

Instantly share code, notes, and snippets.

@pengfeiw
Last active February 20, 2022 03:34
Show Gist options
  • Save pengfeiw/096417bb13e149dfe316b8326d989a33 to your computer and use it in GitHub Desktop.
Save pengfeiw/096417bb13e149dfe316b8326d989a33 to your computer and use it in GitHub Desktop.
关于 JavaScript 模块的一些思考和理解。

Thinking in JavaScript Module

Module Pattern 在 JavaScript 中十分普遍,JSer 在学习和工作中都会使用这种模式。

下面的代码中,会展示一些基础的 Module 用法。

1. 通过匿名函数闭包实现一个模块

var module = (function () {
  // ...模块的具体实现
  var module = {};

  // private 成员
  var _memeber = {};

  // public 成员
  module.member = {};

  // 通过 return 语句返回模块
  return module;
}());

2. 引入全局变量

可以通过给匿名函数传递参数引入全局变量

var module = (function (m1, m2) {
  var module = {};

  // 使用传入的全局变量参数
  module.member = {
    global1: m1,
    global2: m2
  };

  return module;
}(global1, global2));

3. 在多个文件中定义模块

按照上述方式,目前只能在一个文件中定义模块,即模块的实现代码只能在一个闭包函数中执行。需要一种方式,可以使模块在多个文件中定义。我们可以借助匿名函数参数实现。将 module 作为参数传递到匿名函数中,然后扩展传入的模块。

module = (function (m) {

  // 扩展模块
  m.member2 = {};

  return m;
}(module));

防止传入的 module 参数为 undefined

module = (function (m) {

  m.member2 = {};

  return m;
  // 使用 || 操作符,保证传入的 module 不是 undefined
}(module || {}));

4. 多匿名函数定义同一个模块时,使用其他匿名函数中定义的模块成员

module = (function (m) {

  // 存储 m.method
  var old_method = m.method;

  // 重新定义 m.method,还可以在新 method 中使用 old_method
  m.method = function () {
    //...
  };

  return m;
}(module));

5. 克隆和继承

var module2 = (function (p) {

  var my = {};
  // 注意这里不是deep copy,函数或者对象成员只是复制了引用
  for (key in p) {
    if (p.hasOwnProperty(key)) {
      my[key] = old[key];
    }
  }

  var p_method = p.method;
  my.method = function () {
    // override 方法,并且可以使用 p.method
  }

  return my;
}(module));

6. 私有成员跨文件共享

共享私有变量之前,可以调用 _unseal 方法,暴露私有成员,还可以调用 _seal 方法封闭私有成员。

var module = (function () {
  var _private = my._private = my._private || {};
  var _seal = my._seal = my._seal || function () {
    delete my._private;
    delete my._seal;
    delete my._unseal;
  };
  var _unseal = my._unseal = my._unseal || function () {
    my._private = _private;
    my._seal = _seal;
    my._unseal = _unseal;
  };
}());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment