對于瀏覽器來說,這很簡單:我們只需要使用自帶的 btoa 函數(shù):

目前成都創(chuàng)新互聯(lián)已為上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)絡(luò)空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、原州網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。
module.exports = function (string) {
return btoa(string);
};
然而在 Node 里并沒有 btoa 函數(shù)。因此,作為替代,我們需要自己創(chuàng)建一個(gè) Buffer ,然后在上面調(diào)用 buffer.toString() :
module.exports = function (string) {
return Buffer.from(string, 'binary').toString('base64');
};
對于一個(gè)字符串,這兩者都應(yīng)提供其正確的 base64 編碼版本,比如:
var b64encode = require('base64-encode-string');
b64encode('foo'); // Zm9v
b64encode('foobar'); // Zm9vYmFy
現(xiàn)在我們只需要一些方法來檢測我們究竟是在瀏覽器上運(yùn)行還是在 Node 上,好讓我們能保證使用正確的版本。Browserify 和 Webpack 都定義了一個(gè)叫 process.browser 的字段,它會(huì)返回 true (譯者注:即瀏覽器環(huán)境下),然而在 Node 上這個(gè)字段返回 false 。所以我們只需要簡單地:
if (process.browser) {
module.exports = function (string) {
return btoa(string);
};
} else {
module.exports = function (string) {
return Buffer.from(string, 'binary').toString('base64');
};
}
現(xiàn)在我們只需要把我們的文件命名為 index.js ,鍵入 npm publish ,我們就完成了,對不對?好的吧,這個(gè)方法有效,但不幸的是,這種實(shí)現(xiàn)有一個(gè)巨大的性能問題。
V2.0.2
npm install cmd-shim
用于創(chuàng)建不同終端可執(zhí)行腳本
執(zhí)行之后會(huì)在 to 參數(shù)指定的目錄中出現(xiàn)兩個(gè)可執(zhí)行腳本, command-name.cmd 和 command-name
cli.js
index.js
執(zhí)行 index.js 之后,會(huì)在本目錄下出現(xiàn) cli.cmd 和 cli 兩個(gè)文件,可直接在相應(yīng)系統(tǒng)上直接執(zhí)行。
一、什么是閉包?\x0d\x0a“官方”的解釋是:所謂“閉包”,指的是一個(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因而這些變量也是該表達(dá)式的一部分。\x0d\x0a相信很少有人能直接看懂這句話,因?yàn)樗枋龅奶珜W(xué)術(shù)。我想用如何在Javascript中創(chuàng)建一個(gè)閉包來告訴你什么是閉包,因?yàn)樘^閉包的創(chuàng)建過程直接理解閉包的定義是非常困難的。看下面這段代碼: \x0d\x0afunction a(){\x0d\x0a var i=0;\x0d\x0a function b(){\x0d\x0a alert(++i);\x0d\x0a }\x0d\x0a return b;\x0d\x0a}\x0d\x0avar c = a();\x0d\x0ac();\x0d\x0a這段代碼有兩個(gè)特點(diǎn):\x0d\x0a1、函數(shù)b嵌套在函數(shù)a內(nèi)部;\x0d\x0a2、函數(shù)a返回函數(shù)b。\x0d\x0a這樣在執(zhí)行完var c=a()后,變量c實(shí)際上是指向了函數(shù)b,再執(zhí)行c()后就會(huì)彈出一個(gè)窗口顯示i的值(第一次為1)。這段代碼其實(shí)就創(chuàng)建了一個(gè)閉包,為什么?因?yàn)楹瘮?shù)a外的變量c引用了函數(shù)a內(nèi)的函數(shù)b,就是說:\x0d\x0a\x0d\x0a當(dāng)函數(shù)a的內(nèi)部函數(shù)b被函數(shù)a外的一個(gè)變量引用的時(shí)候,就創(chuàng)建了一個(gè)閉包。\x0d\x0a\x0d\x0a我猜想你一定還是不理解閉包,因?yàn)槟悴恢篱]包有什么作用,下面讓我們繼續(xù)探索。\x0d\x0a\x0d\x0a二、閉包有什么作用?\x0d\x0a簡而言之,閉包的作用就是在a執(zhí)行完并返回后,閉包使得Javascript的垃圾回收機(jī)制GC不會(huì)收回a所占用的資源,因?yàn)閍的內(nèi)部函數(shù)b的執(zhí)行需要依賴a中的變量。這是對閉包作用的非常直白的描述,不專業(yè)也不嚴(yán)謹(jǐn),但大概意思就是這樣,理解閉包需要循序漸進(jìn)的過程。\x0d\x0a在上面的例子中,由于閉包的存在使得函數(shù)a返回后,a中的i始終存在,這樣每次執(zhí)行c(),i都是自加1后alert出i的值。\x0d\x0a\x0d\x0a那 么我們來想象另一種情況,如果a返回的不是函數(shù)b,情況就完全不同了。因?yàn)閍執(zhí)行完后,b沒有被返回給a的外界,只是被a所引用,而此時(shí)a也只會(huì)被b引 用,因此函數(shù)a和b互相引用但又不被外界打擾(被外界引用),函數(shù)a和b就會(huì)被GC回收。(關(guān)于Javascript的垃圾回收機(jī)制將在后面詳細(xì)介紹)\x0d\x0a\x0d\x0a三、閉包內(nèi)的微觀世界\x0d\x0a如 果要更加深入的了解閉包以及函數(shù)a和嵌套函數(shù)b的關(guān)系,我們需要引入另外幾個(gè)概念:函數(shù)的執(zhí)行環(huán)境(excution context)、活動(dòng)對象(call object)、作用域(scope)、作用域鏈(scope chain)。以函數(shù)a從定義到執(zhí)行的過程為例闡述這幾個(gè)概念。\x0d\x0a\x0d\x0a1、當(dāng)定義函數(shù)a的時(shí)候,js解釋器會(huì)將函數(shù)a的作用域鏈(scope chain)設(shè)置為定義a時(shí)a所在的“環(huán)境”,如果a是一個(gè)全局函數(shù),則scope chain中只有window對象。\x0d\x0a2、當(dāng)函數(shù)a執(zhí)行的時(shí)候,a會(huì)進(jìn)入相應(yīng)的執(zhí)行環(huán)境(excution context)。\x0d\x0a3、在創(chuàng)建執(zhí)行環(huán)境的過程中,首先會(huì)為a添加一個(gè)scope屬性,即a的作用域,其值就為第1步中的scope chain。即a.scope=a的作用域鏈。\x0d\x0a4、然后執(zhí)行環(huán)境會(huì)創(chuàng)建一個(gè)活動(dòng)對象(call object)。活動(dòng)對象也是一個(gè)擁有屬性的對象,但它不具有原型而且不能通過JavaScript代碼直接訪問。創(chuàng)建完活動(dòng)對象后,把活動(dòng)對象添加到a的作用域鏈的最頂端。此時(shí)a的作用域鏈包含了兩個(gè)對象:a的活動(dòng)對象和window對象。\x0d\x0a5、下一步是在活動(dòng)對象上添加一個(gè)arguments屬性,它保存著調(diào)用函數(shù)a時(shí)所傳遞的參數(shù)。\x0d\x0a6、最后把所有函數(shù)a的形參和內(nèi)部的函數(shù)b的引用也添加到a的活動(dòng)對象上。在這一步中,完成了函數(shù)b的的定義,因此如同第3步,函數(shù)b的作用域鏈被設(shè)置為b所被定義的環(huán)境,即a的作用域。\x0d\x0a\x0d\x0a到此,整個(gè)函數(shù)a從定義到執(zhí)行的步驟就完成了。此時(shí)a返回函數(shù)b的引用給c,又函數(shù)b的作用域鏈包含了對函數(shù)a的活動(dòng)對象的引用,也就是說b可以訪問到a中定義的所有變量和函數(shù)。函數(shù)b被c引用,函數(shù)b又依賴函數(shù)a,因此函數(shù)a在返回后不會(huì)被GC回收。\x0d\x0a\x0d\x0a當(dāng)函數(shù)b執(zhí)行的時(shí)候亦會(huì)像以上步驟一樣。因此,執(zhí)行時(shí)b的作用域鏈包含了3個(gè)對象:b的活動(dòng)對象、a的活動(dòng)對象和window對象,如下圖所示:\x0d\x0a\x0d\x0a如圖所示,當(dāng)在函數(shù)b中訪問一個(gè)變量的時(shí)候,搜索順序是先搜索自身的活動(dòng)對象,如果存在則返回,如果不存在將繼續(xù)搜索函數(shù)a的活動(dòng)對象,依 次查找,直到找到為止。如果整個(gè)作用域鏈上都無法找到,則返回undefined。如果函數(shù)b存在prototype原型對象,則在查找完自身的活動(dòng)對象 后先查找自身的原型對象,再繼續(xù)查找。這就是Javascript中的變量查找機(jī)制。\x0d\x0a\x0d\x0a四、閉包的應(yīng)用場景\x0d\x0a1、保護(hù)函數(shù)內(nèi)的變量安全。以最開始的例子為例,函數(shù)a中i只有函數(shù)b才能訪問,而無法通過其他途徑訪問到,因此保護(hù)了i的安全性。\x0d\x0a2、在內(nèi)存中維持一個(gè)變量。依然如前例,由于閉包,函數(shù)a中i的一直存在于內(nèi)存中,因此每次執(zhí)行c(),都會(huì)給i自加1。\x0d\x0a以上兩點(diǎn)是閉包最基本的應(yīng)用場景,很多經(jīng)典案例都源于此。\x0d\x0a\x0d\x0a五、Javascript的垃圾回收機(jī)制\x0d\x0a在Javascript中,如果一個(gè)對象不再被引用,那么這個(gè)對象就會(huì)被GC回收。如果兩個(gè)對象互相引用,而不再被第3者所引用,那么這兩個(gè)互相引用的對象也會(huì)被回收。因?yàn)楹瘮?shù)a被b引用,b又被a外的c引用,這就是為什么函數(shù)a執(zhí)行后不會(huì)被回收的原因。
最近也在研究這個(gè),Qunee要收費(fèi),直接pass,找到一個(gè)比較合適的:jTopo(Javascript Topology library)是一款完全基于HTML5 Canvas的關(guān)系、拓?fù)鋱D形化界面開發(fā)工具包。
jTopo關(guān)注于數(shù)據(jù)的圖形展示,它是面向開發(fā)人員的,需要進(jìn)行二次開發(fā)。
使用jTopo很簡單,可以快速創(chuàng)建一些關(guān)系圖、拓?fù)涞认嚓P(guān)圖形化的展示。只要您的數(shù)據(jù)之間存在有關(guān)聯(lián)關(guān)系,都可以使用jTopo來進(jìn)行人性化、圖形化的展示。
jTopo的目標(biāo):1.簡單好用 2.靈活擴(kuò)展 3.輕松開發(fā)出類似Visio、在線腦圖、UML建模等類似工具 4.為大數(shù)據(jù)可視化提供解決方案
2.0.0
npm install slash
用于轉(zhuǎn)換 Windows 反斜杠路徑轉(zhuǎn)換為正斜杠路徑 \ = / 。
正斜杠在 Windows 上是可用的,因?yàn)?Windows API 會(huì)自動(dòng)將 / 轉(zhuǎn)換為 \ 。但是如果路徑為擴(kuò)展長度路徑(“\?\”前綴),或包含非 Ascii 字符,則不會(huì)適用于Windows。
slash(path: string): string
全部源碼:
什么是javascript閉包?
javascript允許使用內(nèi)部函數(shù),內(nèi)部函數(shù)可以訪問它們所在的外部函數(shù)中聲明的所有局部變量、參數(shù)和聲明的其他內(nèi)部函數(shù)。當(dāng)其中一個(gè)這樣的內(nèi)部函數(shù)在包含它們的外部函數(shù)之外被調(diào)用時(shí),就會(huì)形成閉包。
簡單的javascript閉包例子:
script
function
f1(){
var
n=999;
nAdd=function(){n+=1}
function
f2(){
alert(n);
}
return
f2;
}
var
result=f1();
result();
//
999
nAdd();
result();
//
1000
/script
在這段代碼中,result實(shí)際上就是閉包f2函數(shù)。它一共運(yùn)行了兩次,第一次的值是999,第二次的值是1000。這證明了,函數(shù)f1中的局部變量n一直保存在內(nèi)存中,并沒有在f1調(diào)用后被自動(dòng)清除。
為什么會(huì)這樣呢?原因就在于f1是f2的父函數(shù),而f2被賦給了一個(gè)全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中,不會(huì)在調(diào)用結(jié)束后,被垃圾回收機(jī)制(garbage
collection)回收。
這段代碼中另一個(gè)值得注意的地方,就是"nAdd=function(){n+=1}"這一行,首先在nAdd前面沒有使用var關(guān)鍵字,因此nAdd是一個(gè)全局變量,而不是局部變量。其次,nAdd的值是一個(gè)匿名函數(shù)(anonymous
function),而這個(gè)匿名函數(shù)本身也是一個(gè)閉包,所以nAdd相當(dāng)于是一個(gè)setter,可以在函數(shù)外部對函數(shù)內(nèi)部的局部變量進(jìn)行操作。
閉包的應(yīng)用:
var
singleton
=
function
()
{
var
privateVariable;
function
privateFunction(x)
{
...privateVariable...
}
return
{
firstMethod:
function
(a,
b)
{
...privateVariable...
},
secondMethod:
function
(c)
{
...privateFunction()...
}
};
}();
這個(gè)單件通過閉包來實(shí)現(xiàn)。通過閉包完成了私有的成員和方法的封裝。匿名主函數(shù)返回一個(gè)對象。對象包含了兩個(gè)方法,方法1可以方法私有變量,方法2訪問內(nèi)部私有函數(shù)。需要注意的地方是匿名主函數(shù)結(jié)束的地方的'()',如果沒有這個(gè)'()'就不能產(chǎn)生單件。因?yàn)槟涿瘮?shù)只能返回了唯一的對象,而且不能被其他地方調(diào)用。這個(gè)就是利用閉包產(chǎn)生單件的方法。
閉包的優(yōu)勢:
(1)不增加額外的全局變量,
(2)執(zhí)行過程中所有變量都是在匿名函數(shù)內(nèi)部。
閉包的缺點(diǎn):
(1)由于閉包會(huì)使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會(huì)造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
(2)閉包會(huì)在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,如果你把父函數(shù)當(dāng)作對象(object)使用,把閉包當(dāng)作它的公用方法(Public
Method),把內(nèi)部變量當(dāng)作它的私有屬性(private
value),這時(shí)一定要小心,不要隨便改變父函數(shù)內(nèi)部變量的值。
本文就為大家介紹這里,如果大家對javascript閉包還是不夠了解,請閱讀相關(guān)文章進(jìn)行補(bǔ)充學(xué)習(xí),謝謝大家的閱讀。
本文題目:javascript的包,js文件包
鏈接分享:http://chinadenli.net/article16/dsephdg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站排名、網(wǎng)站改版、微信公眾號、自適應(yīng)網(wǎng)站、動(dòng)態(tài)網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)