我的JS笔记 -- 模块

作者: 骷髅不会笑丶 | 来源:发表于2017-12-13 22:00 被阅读0次

模块化可以使你的代码低耦合,功能模块直接不相互影响。

模仿块级作用域

JS中没有块级作用域,而是函数作用域,函数中声明的变量和函数不会泄露到外部作用域。那么就可以通过在函数中创建私有变量。

function f() {
    var a = 1;
}
a // ReferenceError: a is not defined

但是这样函数名也是一个全局变量,也有污染全局变量的危险。那么如果使用匿名函数呢?

// 这样会报错,函数声明必须要有标识符
function () {
    var a = 1; 
}

// 仍是会生成全局标识符 
var f = function () {
    var a = 1;
}

JS中可以利用立即执行函数模仿块级作用域,立即函数是一个函数表达式而不是函数声明,不会提升,解析到这行就会立即运行。这样既不会污染全局变量,函数也可以执行。

// 写法一
(function () {
    // 块级作用域
}());

// 写法二
(function () {
    // 块级作用域
})();

// 写法三
(function (fn) {
    fn();
})(function f() {
    // 块级作用域
});

私有变量

JS中函数的参数、局部变量和函数内部定义的函数都不能再函数的外部被访问,所以被称为私有变量。

那么有权访问私有变量和私有函数的公有方法称为特权方法。

特权方法是在对象上创建,一般有两种方式:构造函数定义特权方法和静态私有变量实现特权方法。这两种都是用于为自定义类型创建私有变量和特权方法的。

  • 构造函数定义特权方法;

      function F() {
          var a = 1; // 私有变量
          function sayA() { // 私有函数
              console.log(a);
          }
          this.sayA = sayA; // 特权方法
      }
      var f = new F();
      f.sayA(); // 1
    

缺点是每个实例都会创建一组新方法,违反了构造函数与实例对象相分离的原则。并且,非常耗费内存。

  • 静态私有变量实现特权方法;

      (function () {
          var a = 1; // 私有变量
          function sayA()  { // 私有函数
              console.log(a);
          }
          // 构造函数使用函数表达式,且不使用var,函数声明只能创建局部变量,不使用var的函数表达式可以创建全局变量,让其在私有作用域之外访问
          F = function () {
              //
          };
          F.prototype.sayA = sayA; // 特权方法
      })();
      var f = new F();
      f.sayA(); // 1
    

缺点是私有变量是公用的,所有实例使用的都是相同的私有变量。

模块模式

模块模式是为单例创建私有变量和特权方法。

在JS可以利用立即执行函数和闭包创建模块。

模块模式需要具备两个必要条件:

  1. 必须有外部的封闭函数, 该函数必须至少被调用一次( 每次调用都会创建一个新的模块实例);

  2. 封闭函数必须返回至少一个内部函数, 这样内部函数才能在私有作用域中形成闭包, 并且可以访问或者修改私有的状态;

    var f = function () {
    var a = 1; // 私有变量
    return { // 函数调用后返回一个包含公开属性和方法的对象
    sayA: function () { // 特权方法,通过闭包可以在外部调用时访问内部私有变量
    console.log(a);
    }
    }
    };
    f().sayA(); // 1

利用匿名函数自执行改写

var f = (function () {
    var a = 1; // 私有变量
    return { // 函数调用后返回一个包含公开属性和方法的对象
        sayA: function () {  // 特权方法,通过闭包可以在外部调用时访问内部私有变量
            console.log(a);
        }
    }
})();
f.sayA(); // 1

更多文章在 这里 ,觉得不错希望点个 star

相关文章

网友评论

    本文标题:我的JS笔记 -- 模块

    本文链接:https://www.haomeiwen.com/subject/rbttwxtx.html