最近在学习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(); //

JavaScript中为什么使用立即执行函数来封装模块?的更多相关文章

  1. JavaScript中的闭包与匿名函数

    知识内容: 1.预备知识 - 函数表达式 2.匿名函数 3.闭包 一.函数表达式 1.定义函数的两种方式 函数声明: 1 function func(arg0, arg1, arg2){ 2 // 函 ...

  2. JavaScript中常见的数组操作函数及用法

    JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...

  3. JavaScript中常见的字符串操作函数及用法

    JavaScript中常见的字符串操作函数及用法 最近几次参加前端实习生招聘的笔试,发现很多笔试题都会考到字符串的处理,比方说去哪儿网笔试题.淘宝的笔试题等.如果你经常参加笔试或者也是一个过来人,相信 ...

  4. 一篇文章把你带入到JavaScript中的闭包与高级函数

    在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. funct ...

  5. 使用 JavaScript 中的 window 对象执行计时操作,完成一个抽奖程序

    查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 window 对象执行计时操作,完成一个抽奖程序 实现思路: 在 HTML 页面中放置背景图片.转盘和指针 3 张图片,并设置指 ...

  6. javascript中的两个定时函数setTimeOut()和setInterVal()的区别

    js中经常性要用到间隔几秒或暂停几秒执行某个函数, 简单介绍我从网上收集到setTimeOut()和setInterVal()的区别1.setInterVal()介绍 1)定义 setInterval ...

  7. JavaScript中的闭包和匿名函数

    JavaScript中的匿名函数及函数的闭包   1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...

  8. javascript 中break、 continue、函数不能重载

    在javascript中,break与continue有着显著的差别. 如果遇到break语句,会终止最内层循环,无论后面还有多少计算. 如果遇到continue,只会终止此次循环,后面的自循环依然执 ...

  9. 谈谈javascript中的变量提升还有函数提升

    在很多面试题中,经常会看到关于变量提升,还有函数提升的题目,所以我就写一篇自己理解之后的随笔,方便之后的查阅和复习. 首先举个例子 foo();//undefined function foo(){ ...

随机推荐

  1. 苹果手机的SB系列(4)你让我除了退出还能按哪个键

    我不知道,他们哪里来的自信,自己的机子就不死机?不设置重新启动? 看看下面这个界面,我按哪个键,全部是灰色的! 今天还有一事纪念,0.4m高的坠地,外屏碎掉了.

  2. 浅谈C中操作字符串函数的用法(一)

    按照内核string.h中函数的顺序进行大概的介绍,若干函数会给出一个简单的例子.有不足之处还希望各位看到的留言告知. 一.memcpy: 函数原型:extern void * memcpy(void ...

  3. lr12脚本参数化

    1.注册.登录.获取商品列表lr脚本 Action() {        lr_save_string("192.168.46.129:8080","IP"); ...

  4. MySql数据库通过idb和frm恢复

    简单粗暴 恢复user表 1.先建立和之前user表一样的表结构.就是执行create table user .... ,执行完,数据库目录下就会建立user.ibd文件(当然还有其他的) 2.执行 ...

  5. Python2.0 与 3.0 的区别

    Python 2.0 =默认编码=ASSIC=不支持中文 Python 3.0 =默认编码=UNICODE=默认支持中文   In summary : Python 2.x is legacy, Py ...

  6. jquery添加节点时能有点击事件

    <script>            var n=0;            $(".dj").on('click',function(){              ...

  7. CentOS6.5 - yum对Mysql的安装与配置

    一.mysql的安装 1.查看是否安装mysql [root@localhost ~]# rpm -qa | grep mysql 如果有进行卸载(以下三种方式选一种即可): -.el6.x86_64 ...

  8. mongo aggregate 删除重复数据

    $group 按照什么排序, 关照 _id 这个是排序的依据 $match 这个从排序的结果内抽取 count 大于一的 allDiskUse  如果内存配置比较小, 设置这个才能运行, 否则会崩. ...

  9. 初读"Thinking in Java"读书笔记之第四章 ---控制执行流程

    true和false Java不允许将数字作为布尔值使用. 所有条件表达式都将布尔值作为判断条件,决定执行路径. if-lese 迭代 while,do-while,for为三个迭代语句. ,逗号操作 ...

  10. Unity ECS 初探

    1.安装 安装两个包 2.初探 实例化 注:实例化的实体并不会在Hierarchy视图里面显示,可在EntityDebugger窗口里面显示,因此需要显示的话需要添加Rendermeshcompone ...