RequiereJs学习笔记——RequireJS的由来和垃圾回收机制理解的闭包

Why?为什么要使用RequireJs?

一个程序员,不管注释写的再好,总是会难以维护大型项目的代码。100行没问题,1000行没问题,3000行呢?5000行呢?那我光是浏览一遍都得花很多时间,极大的浪费了精力。

那怎么办呢?拆。

把一个3000行的项目拆成几百行几百行的小项目(按组件)。最傻的方式就是写一个Scrip

/*topbar区域代码*/
var $topbar=$('topbar')
//省略100行
$topbar.on('click',function(){
  console.log('topbar')
})
/*$banners区域代码*/
var $banners=$('banners')
//省略100行
$banners.on('click',function(){
  console.log('topbar')
})
/*slides区域代码*/
var $slides=('slides')
//省略100行
$slides.on('click',function(){
  console.log('topbar')
})

这样就成功的把代码分成了几个部分。我们十分开心的把代码们都隔开了,不会找错修改的位置了。

但是这样又产生了一个问题,如果哪个人手贱硬要在不同部分之间调用怎么办呢?我本来划分的好好的不同段代码又会变得杂乱无章,无法整理。

闭包问题:

于是有一个聪明的前端就想到了使用立即执行函数来进行隔离,让不同区域之间的代码变成函数内代码,也就是把它做成局部变量放在函数里。(顺带一提,ES6中,立即执行函数是一句废话,因为有let的存在。)

function xxx(){

var $topbar =$('#topbar')

$topbar.on('click'),function(){

console.log('topbar')

}

出了函数作用域的块,$topbar就是Undefined,这样就能做到消除全局变量了。

但是这样又产生了一个问题,我们又重新把函数xxx()变成了全局变量。这就很僵硬,我们并没有消灭掉全局变量,消灭掉一个又使用了一个。

于是,又有一个聪明的前端想到了使用!function.

这么做的优点是,我将无法越权修改模块。这就是立即执行函数的意义,可以将环境分割开,让各模块之间不互相干扰。

然而写着写着突然发现了一个新需求:既然已经隔开了,但是我现在想在其他模块上做一个功能需要调用到这个作用域内的函数,又怎么办呢?

函数作用域是不可能互相访问的,我们无法把作用域打通,但是我们可以做一个桥梁。

每当我们新生成一个作用域,它就相当于一个孤岛。

那么想让两个作用域交流怎么办呢?

前端们自然就想到了在函数内使用window.xxxyyy=xxxyyy,将函数内的xxxyyy映射到window上,这样全局不就都可以访问了吗?真是机智。

但是这样就又发生了一个问题,我们将username映射到了全局。如果一个不小心误修改啥的怎么办呢?还是不妥。

我们需要的是什么?是让username只能读,不能写。

于是:

window.userGetter={

nameGetter:function(){

return user.name

},

ageGetter:function(){

return user.age

}

}

我们使用了一次闭包,将这个问题解决了。别的作用域只能读取user,不能改user.

闭包在哪?

在这里说说我的理解。

闭包的用途就是如上:有一个独立的作用域,可以通过全局变量直接将内部的变量映射出去。但是我暴露出去就会有一定的风险,容易被人修改,于是我就不暴露一个变量,而是暴露一个函数。这个函数可以修改这个变量,但是只做有限的操作。外部调取只知道函数名而去访问它,不知道实际上自己操作的是哪个变量名,从而对变量的值进行保护,闭包就是一种作用域的特殊使用方式。

如果要个人做一个定义:

闭包:如果一个函数,它的内部使用了它外部的变量,那么这个函数和这个变量就组合成了一个闭包。

而闭包的作用机制,我认为用JS的垃圾回收机制来说明可能比较清晰明了。

如果我定义一个函数a,并在函数a内写了return b.

然后定义并调用 var fb=a();

那么fb,就是return b 闭包函数的引用。在我执行var fb后,调用了a(),作用域链为函数b→a()→window.

fb会依次往上寻找,直到找到变量为止(找不到则为undefined)

JS垃圾回收机制是不引用则销毁,而这里我们可以看到,作用域链中a()被fb引用,而b被a()引用,也就是说只要fb的引用存在,那么b就一直不会被销毁。

顺便一提,方法访问变量,变量存在内存中,这样做应该会让内存使用的更多才对。

——————————————————————————————————————————————

回到正题。这么使用似乎已经解决了所有问题。但是很快的,会搞事的前端又觉得不爽了。

代码根本没有关联,为啥要放在一个文件里?太sb了。分开吧。

于是:

拆成topbar.js,slide.js,banner.js,他们之间根本无法互相影响。完美!简单粗暴的模块化!!搞那么多弯弯绕绕干嘛!!!还不如一个切图仔想的办法好!!!

前端工程师:你呀,毕竟Naive.

那我有些功能写了一遍并不想再写一遍,比如topbar和banner有相近似的功能,我就是想用他们之中共通的部分,又怎么办呢?写个插件吧。头疼的事又来了,他们之间没法互相访问啊!我写了也没法在其他JS文件中调用。你这样模块化是不是略僵硬了?比如:

new Plugin({element:'#banners>slides.js.'})

写了这个插件之后,我就只能先调用plugin而不能调用别的了。顺序固定了。

而我们知道,两个局部作用域,如果没有window,是永远无法调用其他部分的。

但是分JS文件后,我这么做都是白费功夫,一旦我要依赖,还是要暴露到全局。

暴露到全局的变量太多,太烦了。于是聪明的前端先做一个window.app={},然后将所有东西都挂载在window.app里。那么我所有的调用都是调用app里的,只使用了一个全局变量。是不是跨时代的做法!!(旁人:兄弟,你这不是骗自己吗...该暴露的一个没少啊)

而这个方案,在前端维持了很长一段时间。最著名的库就是:

Jquery($符号)、YUI等。他们都是这么做的

直到requireJs的出现。

Jquery的做法是:分割变量不就是需要立即执行函数吗,那传给我,我帮你执行。上面的需求如果用JQ做,那么我把它挂载在JQ上:

var Plugin=$.Plugin

然后再从$上去取我要的函数。而这种方式,我们叫做命名空间(所有命名都是以同一个空间作为挂载)

requireJS:我觉得你这个方法不错,那我....我就把命名空间的名字固定一下吧。(骗star吗兄弟!!)

window.require(['./plugin.js'],function(Plugin ))

接着就只需要写main.js了,main.js声明了自己依赖了三个js,分别为A\B\C.

ABC里进行了分类,声明了依赖的顺序,全部加载完后就会执行main.js

QQ图片20170613134855
QQ图片20170613134855

于是RequireJS就成为了一个很棒棒的库,一直到了今天.....

嗯,接下来就是学习如何使用了,这个坑慢慢填。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容