<span id="mktg5"></span>

<i id="mktg5"><meter id="mktg5"></meter></i>

        <label id="mktg5"><meter id="mktg5"></meter></label>
        最新文章專題視頻專題問答1問答10問答100問答1000問答2000關鍵字專題1關鍵字專題50關鍵字專題500關鍵字專題1500TAG最新視頻文章推薦1 推薦3 推薦5 推薦7 推薦9 推薦11 推薦13 推薦15 推薦17 推薦19 推薦21 推薦23 推薦25 推薦27 推薦29 推薦31 推薦33 推薦35 推薦37視頻文章20視頻文章30視頻文章40視頻文章50視頻文章60 視頻文章70視頻文章80視頻文章90視頻文章100視頻文章120視頻文章140 視頻2關鍵字專題關鍵字專題tag2tag3文章專題文章專題2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章專題3
        問答文章1 問答文章501 問答文章1001 問答文章1501 問答文章2001 問答文章2501 問答文章3001 問答文章3501 問答文章4001 問答文章4501 問答文章5001 問答文章5501 問答文章6001 問答文章6501 問答文章7001 問答文章7501 問答文章8001 問答文章8501 問答文章9001 問答文章9501
        當前位置: 首頁 - 科技 - 知識百科 - 正文

        JavaScript的引用在Node.js中的具體介紹

        來源:懂視網 責編:小采 時間:2020-11-27 20:23:00
        文檔

        JavaScript的引用在Node.js中的具體介紹

        JavaScript的引用在Node.js中的具體介紹:這篇文章主要介紹了Node.js中看JavaScript的引用的相關資料,需要的朋友可以參考下早期學習 Node.js 的時候 (2011-2012),有挺多是從 PHP 轉過來的,當時有部分人對于 Node.js 編輯完代碼需要重啟一下表示麻煩(PHP不需要這個過程),于是社區里的朋友就開
        推薦度:
        導讀JavaScript的引用在Node.js中的具體介紹:這篇文章主要介紹了Node.js中看JavaScript的引用的相關資料,需要的朋友可以參考下早期學習 Node.js 的時候 (2011-2012),有挺多是從 PHP 轉過來的,當時有部分人對于 Node.js 編輯完代碼需要重啟一下表示麻煩(PHP不需要這個過程),于是社區里的朋友就開

        這篇文章主要介紹了Node.js中看JavaScript的引用的相關資料,需要的朋友可以參考下

        早期學習 Node.js 的時候 (2011-2012),有挺多是從 PHP 轉過來的,當時有部分人對于 Node.js 編輯完代碼需要重啟一下表示麻煩(PHP不需要這個過程),于是社區里的朋友就開始提倡使用 node-supervisor 這個模塊來啟動項目,可以編輯完代碼之后自動重啟。不過相對于 PHP 而言依舊不夠方便,因為 Node.js 在重啟以后,之前的上下文都丟失了。

        雖然可以通過將 session 數據保存在數據庫或者緩存中來減少重啟過程中的數據丟失,不過如果是在生產的情況下,更新代碼的重啟間隙是沒法處理請求的(PHP可以,另外那個時候 Node.js 還沒有 cluster)。由于這方面的問題,加上本人是從 PHP 轉到 Node.js 的,于是從那時開始思考,有沒有辦法可以在不重啟的情況下熱更新 Node.js 的代碼。

        最開始把目光瞄向了 require 這個模塊。想法很簡單,因為 Node.js 中引入一個模塊都是通過 require 這個方法加載的。于是就開始思考 require 能不能在更新代碼之后再次 require 一下。嘗試如下:

        a.js

        b.js

        兩個 JS 文件寫好之后,從 a.js 啟動,刷新頁面會輸出 b.js 中的 1024,然后修改 b.js 文件中導出的值,例如修改為 2048。再次刷新頁面依舊是原本的 1024。

        再次執行一次 require 并沒有刷新代碼。require 在執行的過程中加載完代碼之后會把模塊導出的數據放在 require.cache 中。require.cache 是一個 { } 對象,以模塊的絕對路徑為 key,該模塊的詳細數據為 value。于是便開始做如下嘗試:

        a.js

        再次 require 之前,將 require 之上關于該模塊的 cache 清理掉后,用之前的方法再次測試。結果發現,可以成功的刷新 b.js 的代碼,輸出新修改的值。

        了解到這個點后,就想通過該原理實現一個無重啟熱更新版本的 node-supervisor。在封裝模塊的過程中,出于情懷的原因,考慮提供一個類似 PHP 中 include 的函數來代替 require 去引入一個模塊。實際內部依舊是使用 require 去加載。以b.js為例,原本的寫法改為 var b = include(‘./b'),在文件 b.js 更新之后 include 內部可以自動刷新,讓外面拿到最新的代碼。

        但是實際的開發過程中,這樣很快就碰到了問題。我們希望的代碼可能是這樣:

        web.js

        但按照這個目標封裝include的時候,我們發現了問題。無論我們在include.js內部中如何實現,都不能像開始那樣拿到新的 b.num。

        對比開始的代碼,我們發現問題出在少了 b = xx。也就是說這樣寫才可以:

        web.js

        修改成這樣,就可以保證每次能可以正確的刷新到最新的代碼,并且不用重啟實例了。讀者有興趣的可以研究這個include是怎么實現的,本文就不深入討論了,因為這個技巧使用度不高,寫起起來不是很優雅[1],反而這其中有一個更重要的問題——JavaScript的引用。

        JavaScript 的引用與傳統引用的區別

        要討論這個問題,我們首先要了解 JavaScript 的引用于其他語言中的一個區別,在 C++ 中引用可以直接修改外部的值:

        而在 JavaScript 中:

        我們發現與 C++ 不同,根據上面代碼 ① 可知 JavaScript 中并沒有傳遞一個引用,而是拷貝了一個新的變量,即值傳遞。根據 ② 可知拷貝的這個變量是一個可以訪問到對象屬性的“引用”(與傳統的 C++ 的引用不同,下文中提到的 JavaScript 的引用都是這種特別的引用)。這里需要總結一個繞口的結論:Javascript 中均是值傳遞,對象在傳遞的過程中是拷貝了一份新的引用。

        為了理解這個比較拗口的結論,讓我們來看一段代碼:

        通過這個例子我們可以看到,data 雖然像一個引用一樣指向了 obj.data,并且通過 data 可以訪問到 obj.data 上的屬性。但是由于 JavaScript 值傳遞的特性直接修改 data = xxx 并不會使得 obj.data = xxx。

        打個比方最初設置 var data = obj.data 的時候,內存中的情況大概是:

        | Addr | 內容 | 
        |----------|-------- 
        | obj.data | 內存1 |
        | data | 內存1 |

        所以通過 data.xx 可以修改 obj.data 的內存1。

        然后設置 data = xxx,由于 data 是拷貝的一個新的值,只是這個值是一個引用(指向內存1)罷了。讓它等于另外一個對象就好比:

        | Addr | 內容 |
         |----------|-------- 
        | obj.data | 內存1 || data | 內存2 |

        讓 data 指向了新的一塊內存2。

        如果是傳統的引用(如上文中提到的 C++ 的引用),那么 obj.data 本身會變成新的內存2,但 JavaScript 中均是值傳遞,對象在傳遞的過程中拷貝了一份新的引用。所以這個新拷貝的變量被改變并不影響原本的對象。

        Node.js 中的 module.exports 與 exports

        上述例子中的 obj.data 與 data 的關系,就是 Node.js 中的 module.exports 與 exports 之間的關系。讓我們來看看 Node.js 中 require 一個文件時的實際結構:

        所以很自然的:

        Node.js 中的 exports 就是拷貝的一份 module.exports 的引用。通過 exports 可以修改Node.js 當前文件導出的屬性,但是不能修改當前模塊本身。通過 module.exports 才可以修改到其本身。表現上來說:

        這是二者表現上的區別,其他方面用起來都沒有差別。所以你現在應該知道寫module.exports.xx = xxx; 的人其實是多寫了一個module.。

        更復雜的例子

        為了再練習一下,我們在來看一個比較復雜的例子:

        按照開始的結論我們可以一步步的來看這個問題:

        內部結構:

        | Addr | 內容 | |---------|-------------|
        | a | 內存1 {n:1} | | b | 內存1 |

        繼續往下看:

        a 雖然是引用,但是 JavaScript 是值傳的這個引用,所以被修改不影響原本的地方。

        | Addr | 內容 | |-----------|-----------------------|
        | 1) a | 內存2({n:2}) | | 2) 內存1.x | 內存2({n:2}) |
        | 3) b | 內存1({n:1, x:內存2}) |

        所以最后的結果

        a.x 即(內存2).x ==> {n: 2}.x ==> undefined
        b.x 即(內存1).x ==> 內存2 ==> {n: 2}

        總結

        JavaScrip t中沒有引用傳遞,只有值傳遞。對象(引用類型)的傳遞只是拷貝一個新的引用,這個新的引用可以訪問原本對象上的屬性,但是這個新的引用本身是放在另外一個格子上的值,直接往這個格子賦新的值,并不會影響原本的對象。本文開頭所討論的 Node.js 熱更新時碰到的也是這個問題,區別是對象本身改變了,而原本拷貝出來的引用還指向舊的內存,所以通過舊的引用調用不到新的方法。

        Node.js 并沒有對 JavaScript 施加黑魔法,其中的引用問題依舊是 JavaScript 的內容。如 module.exports 與 exports 這樣隱藏了一些細節容易使人誤會,本質還是 JavaScript 的問題。

        注[1]:

        老實說,模塊在函數內聲明有點譚浩強的感覺。

        把 b = include(xxx) 寫在調用內部,還可以通過設置成中間件綁定在公共地方來寫。

        除了寫在調用內部,也可以導出一個工廠函數,每次使用時 b().num 一下調用也可以。

        還可以通過中間件的形式綁定在框架的公用對象上(如:ctx.b = include(xxx))。

        要實現這樣的熱更新必須在架構上就要嚴格避免舊代碼被引用的可能性,否則很容易寫出內存泄漏的代碼。

        聲明:本網頁內容旨在傳播知識,若有侵權等問題請及時與本網聯系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com

        文檔

        JavaScript的引用在Node.js中的具體介紹

        JavaScript的引用在Node.js中的具體介紹:這篇文章主要介紹了Node.js中看JavaScript的引用的相關資料,需要的朋友可以參考下早期學習 Node.js 的時候 (2011-2012),有挺多是從 PHP 轉過來的,當時有部分人對于 Node.js 編輯完代碼需要重啟一下表示麻煩(PHP不需要這個過程),于是社區里的朋友就開
        推薦度:
        標簽: 中的 js 引用
        • 熱門焦點

        最新推薦

        猜你喜歡

        熱門推薦

        專題
        Top
        主站蜘蛛池模板: 免费看又黄又无码的网站| 一区二区三区免费视频播放器| 久久午夜夜伦鲁鲁片免费无码| 亚洲熟伦熟女新五十路熟妇| 无码毛片一区二区三区视频免费播放 | 免费人成大片在线观看播放| 免费jjzz在线播放国产| 一级做a爰片久久毛片免费陪 | 免费黄色毛片视频| 最近免费字幕中文大全视频| 亚洲A∨无码一区二区三区| 性xxxx视频免费播放直播| 久久亚洲AV成人无码电影| 在线观看成人免费视频不卡| 色偷偷亚洲女人天堂观看欧| 午夜影视在线免费观看| 最好2018中文免费视频| 亚洲色大成网站www永久一区| 最近免费中文字幕中文高清 | 香港特级三A毛片免费观看| 亚洲伦乱亚洲h视频| 韩日电影在线播放免费版| 精品无码一区二区三区亚洲桃色 | 亚洲精品成人av在线| 国产成人福利免费视频| 亚洲国产精品成人综合色在线| 免费很黄很色裸乳在线观看| 免费91麻豆精品国产自产在线观看 | 春暖花开亚洲性无区一区二区| 国产亚洲精品自在线观看| 7x7x7x免费在线观看| 亚洲avav天堂av在线网毛片| 亚洲国产精品成人精品无码区| 又粗又大又黑又长的免费视频 | 精品免费视在线观看| 2020亚洲男人天堂精品| 亚洲AV日韩精品一区二区三区| 亚洲电影免费在线观看| 亚洲国产欧美日韩精品一区二区三区| 91麻豆精品国产自产在线观看亚洲| 国产91色综合久久免费分享|