最近在学习JavaScript基础,在学习到面向对象编程时,学习到在JavaScript中实现模块化的方法,其中一个重要的点是如何封装私有变量。

实现封装私有变量的方法主要是:

  1. 使用构造函数

    function StringBuilder() {
    var buffer = []; this.add = function (str) {
    buffer.push(str);
    }; this.toString = function () {
    return buffer.join('');
    };
    }
    // 上面这种做法有个缺点,就是每生成一个新的实例,其中的方法就会生成一个新的实例,造成内存浪费,因此做如下改进
    function StringBuilder() {
    this._buffer = [];
    } StringBuilder.prototype = {
    constructor: StringBuilder,
    add: function (str) {
    this._buffer.push(str);
    },
    toString: function () {
    return this._buffer.join('');
    }
    };
    // 此时所有实例会共享这两个方法,不会重复生成
    // 但是问题又来了,我们封装的私有变量变得不私有了,在外部可以直接修改_buffer,如
    var sb = new StringBuilder();
    sb._buffer = 'hello, sb';
  2. 使用立即执行函数
    var module = (function() {
    function StringBuilder() {
    this._buffer = [];
    } StringBuilder.prototype = {
    constructor: StringBuilder,
    add: function (str) {
    this._buffer.push(str);
    },
    toString: function () {
    return this._buffer.join('');
    }
    }; function createStringBuilder() {
    var _sb = new StringBuilder();
    return {
    add: StringBuilder.prototype.add.bind(_sb),
    toString: StringBuilder.prototype.toString.bind(_sb)
    };
    } return {
    createStringBuilder: createStringBuilder
    }; })(); console.log(module); // { createStringBuilder: [Function: createStringBuilder] }
    var sb = module.createStringBuilder();
    sb.add('hello');
    sb.add('爱编程的小菜鸟');
    console.log(sb.toString()); // hello爱编程的小菜鸟

在立即执行函数中,重点在于createStringBuilder这个函数,这个函数实现了内外对接的接口,对内保护了StringBuilder的私有成员,对外又能提供需要访问的接口,实现了真正的私有变量封装。下面我们用一个简单的例子对上面的三种方式进行对比:

// 构造函数,var1无法被外界修改,但是每生成一个实例,fn都会被拷贝
function Class1() {
var var1 = 10;
this.fn = function() {
console.log(var1);
var1 += 1;
};
}
var c10 = new Class1();
var c11 = new Class1();
console.log(c10.var1); // undefined,变量不可被访问
console.log(c10 === c11); // false
c10.fn(); //
c11.fn(); //
c10.fn(); //
c11.fn(); // // 改进一下
function Class2() {
this._var1 = 10;
} Class2.prototype = {
constructor: Class2,
fn: function() {
console.log(this._var1);
this._var1 += 1;
}
};
var c20 = new Class2();
var c21 = new Class2();
c20.fn(); //
c20.fn(); //
c21.fn(); //
c21.fn(); //
console.log(c20._var1); // 11,变量可被访问
console.log(c20.fn === c21.fn); // true // 为了解决上述问题
var m = (function() {
function Class3() {
this.var1 = 10
}
Class3.prototype = {
constructor: Class3,
fn: function() {
console.log(this.var1);
this.var1 += 1;
}
}; function createClass3() {
var c3 = new Class3();
return {
fn: Class3.prototype.fn.bind(c3)
};
} return {
createClass3: createClass3
}
})();
var c30 = new m.createClass3();
var c31 = new m.createClass3();
c30.fn(); //
c30.fn(); //
c31.fn(); //
c31.fn(); //

最新文章

  1. VB6 GDI+ 入门教程[8] Bitmap魔法(1):创建
  2. 【转】C++析构函数为什么要为虚函数
  3. TFSAPI
  4. CSS常用十大技巧
  5. Android之帧动画2
  6. 关于iOS中SQLITE句柄的使用的细节
  7. Ubuntu 16.04 - 64bit 解压 rar 报错 Parsing Filters not supported
  8. KMP入门(匹配)
  9. Android中Cursor类的概念和用法
  10. SQL window身份登陆 SQL server不能登陆
  11. mkbundle(1) - Linux man page
  12. Docker存储驱动之AUFS简介
  13. markdown简述
  14. 使用.NET开发AutoCAD——C#/AutoCAD 2018/ObjectArx/二次开发入门(二)
  15. SSH 之 Spring的源码(一)——Bean加载过程
  16. Elasticsearch+Mongo亿级别数据导入及查询实践
  17. App测试流程及测试点(个人整理版)
  18. Feign性能优化注意事项
  19. python自学第12天 模块定义,导入,内置模块
  20. ArcEngine不同种类的工作空间建立查询ICursor时“超出系统资源”

热门文章

  1. 2015-10-27 C#3
  2. Safari 里的javascript 里不能用submit作为函数名
  3. sqlparameters
  4. C++各种优化
  5. 12月4日学习爬虫007.使用Urllib模块进行简单网页爬取
  6. python笔记21-内置函数
  7. VGG网络结构
  8. 【leetcode198 解题思路】动态规划
  9. java基础知识—循环结构
  10. 自学python之路(day6)