JavaScript中为什么使用立即执行函数来封装模块?
最近在学习JavaScript基础,在学习到面向对象编程时,学习到在JavaScript中实现模块化的方法,其中一个重要的点是如何封装私有变量。
实现封装私有变量的方法主要是:
- 使用构造函数
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'; - 使用立即执行函数
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中为什么使用立即执行函数来封装模块?的更多相关文章
- JavaScript中的闭包与匿名函数
知识内容: 1.预备知识 - 函数表达式 2.匿名函数 3.闭包 一.函数表达式 1.定义函数的两种方式 函数声明: 1 function func(arg0, arg1, arg2){ 2 // 函 ...
- JavaScript中常见的数组操作函数及用法
JavaScript中常见的数组操作函数及用法 昨天写了个帖子,汇总了下常见的JavaScript中的字符串操作函数及用法.今天正好有时间,也去把JavaScript中常见的数组操作函数及用法总结一下 ...
- JavaScript中常见的字符串操作函数及用法
JavaScript中常见的字符串操作函数及用法 最近几次参加前端实习生招聘的笔试,发现很多笔试题都会考到字符串的处理,比方说去哪儿网笔试题.淘宝的笔试题等.如果你经常参加笔试或者也是一个过来人,相信 ...
- 一篇文章把你带入到JavaScript中的闭包与高级函数
在JavaScript中,函数是一等公民.JavaScript是一门面向对象的编程语言,但是同时也有很多函数式编程的特性,如Lambda表达式,闭包,高阶函数等,函数式编程时一种编程范式. funct ...
- 使用 JavaScript 中的 window 对象执行计时操作,完成一个抽奖程序
查看本章节 查看作业目录 需求说明: 使用 JavaScript 中的 window 对象执行计时操作,完成一个抽奖程序 实现思路: 在 HTML 页面中放置背景图片.转盘和指针 3 张图片,并设置指 ...
- javascript中的两个定时函数setTimeOut()和setInterVal()的区别
js中经常性要用到间隔几秒或暂停几秒执行某个函数, 简单介绍我从网上收集到setTimeOut()和setInterVal()的区别1.setInterVal()介绍 1)定义 setInterval ...
- JavaScript中的闭包和匿名函数
JavaScript中的匿名函数及函数的闭包 1.匿名函数 2.闭包 3.举例 4.注意 1.匿名函数 函数是JavaScript中最灵活的一种对象,这里只是讲解其匿名函数的用途.匿名函数:就是没 ...
- javascript 中break、 continue、函数不能重载
在javascript中,break与continue有着显著的差别. 如果遇到break语句,会终止最内层循环,无论后面还有多少计算. 如果遇到continue,只会终止此次循环,后面的自循环依然执 ...
- 谈谈javascript中的变量提升还有函数提升
在很多面试题中,经常会看到关于变量提升,还有函数提升的题目,所以我就写一篇自己理解之后的随笔,方便之后的查阅和复习. 首先举个例子 foo();//undefined function foo(){ ...
随机推荐
- 算法:输出一个整数(不用ToString方法)
1.递归实现 static void Main(string[] args) { Console.WriteLine("Pls input a number:"); int p = ...
- Vue入门笔记(二)--基础部分之条件渲染
github地址:https://github.com/iTao9354/basicVue/tree/master/conditional%20rendering(demo01-03) 一.v-if ...
- html入门1
1.HTML超文本标记语言,(Hypertext Markup Language),通过一段内容定义为标题,段落或者图像等,从而让该内容具有结构以及含义 2.W3C:万维网联盟(World Wide ...
- S2T40,第五章
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- C# [Win32] [API] WS_TABSTOP 無效的解決辦法
關鍵: IsDialogMessage function MSG msg; int bRet = 1; while (bRet != 0) { if (PeekMessageW(&msg, ( ...
- java编写ID3决策树
说明:每个样本都会装入Data样本对象,决策树生成算法接收的是一个Array<Data>样本列表,所以构建测试数据时也要符合格式,最后生成的决策树是树的根节点,通过里面提供的showTre ...
- vue使用动态渲染v-model输入框无法输入内容
最近使用ElementUI框架,在动态渲染表单的时候,表单框无法输入内容,但是绑定model的数据是会发生变化 解决方法: 将动态生成的表单对象,深拷贝到 data 对象中 <el-date-p ...
- CEPH集群操作入门--配置
参考文档:CEPH官网集群操作文档 概述 Ceph存储集群是所有Ceph部署的基础. 基于RADOS,Ceph存储集群由两种类型的守护进程组成:Ceph OSD守护进程(OSD)将数据作为对象 ...
- C语言:开平方根sqrt程序02
#include <stdio.h> int sqrt01(int x); void main(void){ int x=49,y; y=sqrt01(x); if(y<0) pri ...
- phpstrom常用快捷键
mark一下 格式化(应设置QQ快捷键) 自动代码提示 Ctrl+Alt+L Ctrl+J 页面查找 页面查找并替换 Ctrl+F Ctrl+R 全局查找 全局查找并替换 ...