運用惰性刪除和定時刪除實現可過期的localStorage緩存_網頁設計

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

localStorage簡介

使用localStorage可以在瀏覽器中存儲鍵值對的數據。經常被和localStorage一併提及的是sessionStorage,它們都可以在當瀏覽器中存儲鍵值對的數據。但是它們之間的區別是:存儲在localStorage的數據可以長期保留;而當頁面會話結束(也就是當頁面被關閉)時,存儲在sessionStorage的數據會被清除。

另外需要注意的是,localStorage中的鍵值對總是以字符串的形式存儲,並且只能訪問當前域名下的數據,不能跨域名訪問。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

localStorage方法

可以通過setItem方法增加了一個鍵值對數據,比如:

localStorage.setItem('name', 'OneMore');

如果該鍵已經存在,那麼該鍵對應的值將被覆蓋。還可以使用getItem方法讀取對應鍵的值數據,比如:

var name = localStorage.getItem('name');

可以使用removeItem方法移除對應的鍵,比如:

localStorage.removeItem('name');

也可以使用clear方法移除當前域名下所有的鍵值對數據,比如:

localStorage.clear();

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

可過期的localStorage緩存

正如上面所提到的,localStorage只能用於長久保存整個網站的數據,保存的數據沒有過期時間,直到手動去刪除。所以要實現可過期的localStorage緩存的中重點就是:如何清理過期的緩存?

惰性刪除

惰性刪除是指,某個鍵值過期后,該鍵值不會被馬上刪除,而是等到下次被使用的時候,才會被檢查到過期,此時才能得到刪除。我們先來簡單實現一下:

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

var lsc = (function (self) {
    var prefix = 'one_more_lsc_'
    /**
     * 增加一個鍵值對數據
     * @param key 鍵
     * @param val 值
     * @param expires 過期時間,單位為秒
     */
    self.set = function (key, val, expires) {
        key = prefix + key;
        val = JSON.stringify({'val': val, 'expires': new Date().getTime() + expires * 1000});
        localStorage.setItem(key, val);
    };
    /**
     * 讀取對應鍵的值數據
     * @param key 鍵
     * @returns {null|*} 對應鍵的值
     */
    self.get = function (key) {
        key = prefix + key;
        var val = localStorage.getItem(key);
        if (!val) {
            return null;
        }
        val = JSON.parse(val);
        if (val.expires < new Date().getTime()) {
            localStorage.removeItem(key);
            return null;
        }
        return val.val;
    };
    return self;
}(lsc || {}));

上述代碼通過惰性刪除已經實現了可過期的localStorage緩存,但是也有比較明顯的缺點:如果一個key一直沒有被用到,即使它已經過期了也永遠存放在localStorage。為了彌補這樣缺點,我們引入另一種清理過期緩存的策略。

歡迎關注微信公眾號:萬貓學社,每周一分享Java技術乾貨。

定時刪除

定時刪除是指,每隔一段時間執行一次刪除操作,並通過限制刪除操作執行的次數和頻率,來減少刪除操作對CPU的長期佔用。另一方面定時刪除也有效的減少了因惰性刪除帶來的對localStorage空間的浪費。

每隔一秒執行一次定時刪除,操作如下:

  1. 隨機測試20個設置了過期時間的key。
  2. 刪除所有發現的已過期的key。
  3. 若刪除的key超過5個則重複步驟1,直至重複500次。

具體實現如下:

var lsc = (function (self) {
    var prefix = 'one_more_lsc_'
    var list = [];
    //初始化list
    self.init = function () {
        var keys = Object.keys(localStorage);
        var reg = new RegExp('^' + prefix);
        var temp = [];
        //遍歷所有localStorage中的所有key
        for (var i = 0; i < keys.length; i++) {
        	//找出可過期緩存的key
            if (reg.test(keys[i])) {
                temp.push(keys[i]);
            }
        }
        list = temp;
    };
    self.init();
    self.check = function () {
        if (!list || list.length == 0) {
            return;
        }
        var checkCount = 0;
        while (checkCount < 500) {
            var expireCount = 0;
            //隨機測試20個設置了過期時間的key
            for (var i = 0; i < 20; i++) {
                if (list.length == 0) {
                    break;
                }
                var index = Math.floor(Math.random() * list.length);
                var key = list[index];
                var val = localStorage.getItem(list[index]);
                //從list中刪除被惰性刪除的key
                if (!val) {
                    list.splice(index, 1);
                    expireCount++;
                    continue;
                }
                val = JSON.parse(val);
                //刪除所有發現的已過期的key
                if (val.expires < new Date().getTime()) {
                    list.splice(index, 1);
                    localStorage.removeItem(key);
                    expireCount++;
                }
            }
            //若刪除的key不超過5個則跳出循環
            if (expireCount <= 5 || list.length == 0) {
                break;
            }
            checkCount++;
        }
    }
    //每隔一秒執行一次定時刪除
    window.setInterval(self.check, 1000);
    return self;
}(lsc || {}));

完整源碼及使用示例

完整源碼及使用示例已上傳到我的GitHub(https://github.com/heihaozi/LocalStorageCache)上,感謝各位小夥伴的Star和Fork。

總結

一種策略可能會有自己的缺點,為了規避相應的缺點,我們可以合理運用多種策略,揚長避短就得到接近完美的解決方案。

微信公眾號:萬貓學社

微信掃描二維碼

獲得更多Java技術乾貨

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

如果我買了SUV 一定承諾給它一趟難忘的旅行_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

有一個好消息是,明天七八月份,西藏拉薩到林芝地區的高等級公路基本能施工完畢並通車,路況非常地好,到時候不限於SUV車型能進藏,各種轎車或摩托車都完全可以從拉薩到林芝往返,大大降低了自駕游的成本和時間,重要的是增加了不少人身安全,進藏再也不是那麼難了。

最後說幾句:

此次參加雪佛蘭SUV最美中國行,是航班成都轉飛拉薩的,自駕游路線由拉薩市中心到林芝地區。自駕車的路線大部分都是土路,旁邊都是施工團隊在工作,經過不少村落,

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

遇到不少牛羊豬群,聽導遊說,撞死一隻牛三萬塊,撞死一隻藏香豬一萬塊,撞死還不能帶走…有一個好消息是,明天七八月份,西藏拉薩到林芝地區的高等級公路基本能施工完畢並通車,路況非常地好,到時候不限於SUV車型能進藏,各種轎車或摩托車都完全可以從拉薩到林芝往返,大大降低了自駕游的成本和時間,重要的是增加了不少人身安全,進藏再也不是那麼難了。祝願每個人的進藏夢,儘早實現!本站聲明:網站內容來源於http://www.auto6s.com/,如有侵權,請聯繫我們,我們將及時處理

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

一圖讀懂十九屆五中全會公報中的美麗中國_貨運

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

2020-11-01

2020-11-01
分享到:
[打印]
字號:[大] [中] [小]

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

Microsoft 將推出更新,幫助用戶移除電腦裡的 Flash Player_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

畢竟 Adobe Flash 已經死透了,現在也是時候將它從電腦系統中清掉了,前幾天告訴大家如何從 MacOS 中移除,而 Microsoft 在近日也宣布了 Windows 的獨立更新軟體包,幫助使用者從設備中將軟體清掉,該更新會在 2021 年初釋出,不過使用上也是有條件的。

Microsoft 將推出更新,幫助用戶移除電腦裡的 Flash Player

這次的獨立更新會為用戶提供足夠的時間為 Adobe Flash 的結束做好準備,Microsoft 解釋道,這個更新將可幫助使用者測試與驗證系統環境,以找出移除 Adobe Flash Player 候可能產生的任何影響。可是還是有一個但書,該更新只顯於刪除由 Windows 版本安裝的 Adobe Flash Player,如果你是從其他來源手動安裝,將不會有刪除的作用。

另外,Microsoft 也警告用戶,這項更新一旦安裝後,你就無法刪除它。此更新可用於所有受支援的 Windows 版本,從 Windows 8.1 起至現在最新的 Windows 10 都能用,不過現在全球還有約莫 1 億用戶,在去年 1 月就已經結束生命的 Windows 7 就不會得到此更新了。

Adobe 也建議用戶盡快從電腦系統中移除 Flash Player,以避免在結束生命後因為不再有安全更新而出現任何的潛在性風險。倘若大家想要快點手動移除 Adobe Flash Player,可以從官網下載解除安裝程式來執行,如果你是使用 Flash Player 測試版,請使用 Adobe Labs 提供的相對應 Flash Player 測試版解除安裝程式。如果是個瀏覽器上隨附的 Adobe Flash Player,則請在瀏覽器中停用該隨附外掛。

◎資料來源:SoftPedia

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

搭建Prometheus平台,你必須考慮的6個因素_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

作者簡介

Loris Degioanni,Sysdig的創始人和CTO,同時還是容器安全工具Falco的創建者。

原文鏈接
https://thenewstack.io/6-things-to-consider-in-a-prometheus-monitoring-platform/

本文轉自Rancher Labs

當前,Prometheus被許多企業和組織廣泛使用,以監控其容器和微服務。但是在這一過程中,大型公司通常會陷入困境:當應用程序數量越來越多的時候,擴展監控指標則是一個十分重大的挑戰。

不斷增長的容器使情況複雜化

相對來說,監控單體環境常常更簡單,因為靜態物理服務器和虛擬機數量是確定的,並且監控指標的數量也是有限的。但是,如今由於容器以及需要向微服務架構遷移,要跟蹤監控的實例程序數量激增。

如果說位於數據中心的服務器是寵物,需要我們不斷關注的話,那麼雲實例則更像牛(因為有很多,你不必關心單個實例),而容器則更像小蜜蜂。它們數量很多,有時每台機器有數百個容器,並且新的容器一直不斷出現,當與諸如Kubernetes的容器編排引擎一起使用時,它們的壽命可能非常短。這使得跟蹤監控它們變得更加困難,而且如果你不小心誤操作的話,它們可能會造成很多損害。

隨着複雜性和分佈式環境的增加,你需要監控的實體數量也在增加。此外,你可能希望監控更多屬性以確保你對正在發生的事情有準確的了解,或者在進行故障排除或事件響應的情況下,可以了解正在發生的事情。在短暫的環境中,後者尤其成問題,因為當你想了解問題的根本原因時,通常相關的資源已經停用,這意味着監控解決方案必須提供一種能夠存儲足夠的歷史記錄以進行取證的方法。

流行的監控工具:Prometheus

越來越多需要雲監控的團隊正在轉向Prometheus,這是一個開源的CNCF項目。Prometheus已成為開發人員用來在雲原生環境中收集和理解指標的首選監控工具。它由一個大型社區支持,有來自700多家公司的6300個貢獻者,有13500個代碼提交和7200個拉取請求。

默認情況下,典型的雲原生應用程序堆棧(如Kubernetes、Ngnix、MongoDB、Kafka、golang等)會暴露Prometheus指標。Prometheus是一個可以垂直彈性伸縮的Go程序,為單個容器或單個主機部署它時十分容易。換言之,一開始使用Prometheus極為容易,你可以輕鬆監控你的第一個Kubernetes集群,但是這也意味着隨着基礎架構的增長,監控會越來越複雜。

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

應用程序增長帶來的擴展問題

隨着環境規模增長,你需要跟蹤監控飛速增長的時間序列數據,並且在數據量達到某個點之後,單個Prometheus實例無法繼續跟蹤監控。這一情況下,最直接的選擇是在整個企業中運行一組Prometheus服務器,但這帶來了一些挑戰。例如,跨數十甚至數百台Prometheus服務器管理和合併數據並不容易。同樣,了解企業工作流程、單點登錄、基於角色的訪問控制以及遵守SLA或合規性也不是容易的問題。隨着應用程序的增長,在不中斷開發人員工作的情況下運行一個全方位的監控解決方案,這將成為一個可管理性和可靠性的問題。

為了解決這一問題,企業採用了許多方法。

簡單的方法是為每個命名空間或每個集群都準備一個單獨的Prometheus服務器。這種方法到一定規模就會難以為繼,此外,它還有一個缺點,那就是會造成大量的斷開的數據孤島。這會使故障排查變得很麻煩,因為大多數問題會跨越多個服務/團隊/集群。不但在每個環境中很難找到相同的指標,你還需要把數據拼接在一起,以試圖了解發生了什麼。

另一個常見方法是使用類似Cortex或Thanos的開源工具來集合多個Prometheus服務器。這些高效的工具可以讓你集中查詢服務器、收集數據然後在統一的dashboard中共享。然而,與任何數據密集型分佈式系統一樣,它們需要大量的技能和資源才能運行。

需要考慮的6個因素

對於那些以Prometheus為起點,然後尋求商業化解決方案以獲得全局監控的公司來說,重要的是,不丟失Prometheus上完成的所有標準化開發工作——dashboard、告警、exporter等。然而,這不是需要考慮的唯一事情,如果你繼續使用Prometheus,需要堅持以下標準:

1、 兼容性,以支持所有Prometheus功能

你的供應商/所使用的工具/SaaS解決方案需要能夠使用任何可產生Prometheus指標的實體程序中消耗數據,無論是本地Kubernetes還是雲服務。相對來說,消耗Prometheus指標微不足道,但是也不要忽略一些小事情,例如將指標提取到存儲中或增加數據時能夠重新標註指標,這樣對你的環境更有意義。這些小事加起來,能夠收集到的數據將會堆積如山、大不相同。

2、 PromQL兼容性

Prometheus查詢語言由Prometheus創建者發明,用於提取存儲在Prometheus中的信息。PromQL能讓你查詢指定服務或指定用戶的指標,它還能匯總或細分數據。例如,你可以使用它显示所有容器中每個應用的CPU使用率。或者僅显示Cassandra容器的數據,並將其显示為每個集群的單個值。可以說,PromQL釋放了Prometheus的真正價值,因此如果將Prometheus的指標集成到一個不完全支持PromQL的產品中,就完全違背了使用Prometheus的初衷。

3、 支持熱插拔

要真正與Prometheus兼容,該解決方案必須能夠支持熱插拔,以便能夠與你現有的dashboard、告警和腳本一起使用。例如,許多使用Prometheus的企業都將Grafana用於dashboard。這個開源工具能夠與Prometheus很好地集成在一起,包括在查詢級別,並且可以用於生成一系列有用的圖表和dashboard。因此,聲稱與Prometheus兼容的商業產品應與Grafana等工具兼容。僅僅說解決方案可以讓你在Grafana中查看数字是遠遠不夠的,你需要能夠按照原樣提取現有的Grafana dashboard,並將它們重新應用於商業解決方案中已安裝的數據。

4、 訪問控制

在評估工具時,訪問控制是另一個你需要考慮的安全問題。能夠使用行業標準協議(包括LDAP、Google Oauth、SAML和OpenID)保護用戶身份驗證,使公司能夠通過基於服務的訪問控制來隔離和保護資源。

5、 故障排查

Kubernetes簡化了部署、彈性伸縮和管理容器化應用程序和微服務。這有助於保持服務的正常運行,但是要識別和解決諸如性能降低、部署失敗和連接錯誤之類的根本問題,你需要能夠從整個環境中收集和可視化基礎架構、應用程序和性能數據。由於無法同時訪問實時信息和上下文數據,因此幾乎不可能關聯環境中的指標,所以你可以更快地解決問題。

6、 與現有告警兼容

最後,如果你正在尋找商業解決方案來幫助解決Prometheus可擴展性問題,請確保它支持所有級別的告警。能夠實現這一目標的關鍵是全面支持Alert Manager功能,而Alert Manager還要求100%的集成和 PromQL兼容性。

如果你找到一個能夠滿足以上標準的商業化工具,你應該能夠輕鬆將其集成到現有的Prometheus中,並且能夠避免公司遇到的可擴展性問題。開發人員有充分的理由喜愛Prometheus,因此在採用商業化方案之前進行全面、盡職的調查將確保他們仍然可以使用自己喜歡的指標。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

東奧主場館建築師 為後疫情時代設計建築_網頁設計

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

摘錄自2020年6月16日公視報導

在後疫情時代,建築該如何防疫也成為全球焦點。東京奧運主場館「新國立競技場」的建築師隈研吾認為,防疫建築必須要注意通風,還有良好的間隔距離,還以京都老街建築,來當成範本。

受到新冠病毒影響,各國陸續進入後疫情時代,不只生活型態改變,就連建築如何防疫也成了各國關注焦點。設計出日本新國立競技場、高輪Gateway車站的日本建築大師隈研吾,指出疫情過後不少建築設計師發現,現今建築的缺點就是太過密閉,很難防疫。

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

隈研吾說:「至今為止的建築或建築業界都是著重在製作「箱型」建築,但是這結果卻是無法讓人類幸福。」因為都市人口集中,寸土寸金,為了講究工作效率,建築多為氣密性高,能用小空間,容納許多人的形式,但這樣反倒容易發生群聚感染。

以京都老街建築為例,隈研吾強調防疫建築就是要跳脫箱型建築,要放棄現在大樓以水泥、玻璃當建材,改為用木材能通風、並有良好間隔距離的傳統老屋形式。

生活環境
建築
國際新聞
日本
東京奧運
通風
公共建築

本站聲明:網站內容來源環境資訊中心https://e-info.org.tw/,如有侵權,請聯繫我們,我們將及時處理

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

Nvidia 終於將 RTX 3000 系列導入筆電中,本月起新機陸續現身_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

距離桌上型電腦用的 GeForce RTX 3000 系列顯卡推出不到半年時間,今日(1/13)Nvidia 宣布將為筆電導入 RTX 3060、RTX 3070 和 RTX 3080 等顯卡,憑藉其新的 Ampere 架構,與過去搭載 RTX 2000 系列的筆電相比擁有顯著的效能提升。

Nvidia 終於將 RTX 3000 系列導入筆電中,本月起新機陸續現身

在這次會中,Nvidia 表示,從 1/26 起將會有超過 70 款遊戲筆電配備 RTX 3070 和 RTX 3080 顯卡,而伴隨 RTX 3060 的推出,採用 RTX 3060 顯卡的筆電也會在 2/2 上市。搭載 RTX 3060 的筆電售價從 999 美元起;RTX 3070 筆電的售價則為 1,299 美元起,Nvidia表示在速度上會比以往的 RTX 2070 系統快上 1.5 倍,並且能提供 1440P、90fps 。RTX 3080 筆電的售價為 1,999 美元起,顯卡記憶體最高達 16GB GDDR6,超越 RTX 3080 PC 版,Nvidia 指出這些筆電將可提供 144oP、100fps 以上的幀速。

這些配備最新 RTX 3000 系列筆電採用的是第三代 Nvidia Max-Q 技術,而其變異版本則專為更輕薄的遊戲筆電而設計,主要在將大部分 GPU 熱能從更緊湊的機身中散出,而 Nvidia 與 OEM 廠商對此進行了更進一步的調整改良,以實現此一目標。Nvidia 表示,最新一代的 Max-Q 筆電將提供前代兩倍的效能,並且在這些筆電中皆運用了 Dynamic Boost 2.0 技術,利用 AI 以幀為單位平衡 CPU、GPU 與 GPU 記憶體之間的電力需求,達到即時平衡的效果。

最新 RTX 3000 系列筆電效能強大,足以運行對硬體要求嚴苛的《Microsoft Flight Simulator》,且 Nvidia 還在這些筆電中加入 WhisperMode 2.0,另外 AI 還能管理風扇速度和遊戲設定以保持所需的音位。

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

深入理解JS:var、let、const的異同_網頁設計公司

網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

透過選單樣式的調整、圖片的縮放比例、文字的放大及段落的排版對應來給使用者最佳的瀏覽體驗,所以不用擔心有手機版網站兩個後台的問題,而視覺效果也是透過我們前端設計師優秀的空間比例設計,不會因為畫面變大變小而影響到整體視覺的美感。

目錄

  • 序言
  • var 與 let 的區別
    • 作用域
    • 重複聲明
    • 綁定全局對象
    • 變量提升與暫存死區
  • let 與 const 異同
  • 參考

1.序言

var、let 和 const 都是 JavaScript 中用來聲明變量的關鍵字,並且 let 和 const 關鍵字是在 ES6 中才新增的。既然都是用來聲明變量的,那它們之間有什麼區別呢?讓我們來一探究竟。

2.var 與 let 的區別

(1)作用域

用 var 聲明的變量的作用域是它當前的執行上下文,即如果是在任何函數外面,則是全局執行上下文,如果在函數裏面,則是當前函數執行上下文。換句話說,var 聲明的變量的作用域只能是全局或者整個函數塊的。

而 let 聲明的變量的作用域則是它當前所處代碼塊,即它的作用域既可以是全局或者整個函數塊,也可以是 if、while、switch等用{}限定的代碼塊。

另外,var 和 let 的作用域規則都是一樣的,其聲明的變量只在其聲明的塊或子塊中可用。

示例代碼:

function varTest() {
  var a = 1;

  {
    var a = 2; // 函數塊中,同一個變量
    console.log(a); // 2
  }

  console.log(a); // 2
}

function letTest() {
  let a = 1;

  {
    let a = 2; // 代碼塊中,新的變量
    console.log(a); // 2
  }

  console.log(a); // 1
}

varTest();
letTest();

從上述示例中可以看出,let 聲明的變量的作用域可以比 var 聲明的變量的作用域有更小的限定範圍,更具靈活。

(2)重複聲明

var 允許在同一作用域中重複聲明,而 let 不允許在同一作用域中重複聲明,否則將拋出異常。

var 相關示例代碼:

var a = 1;
var a = 2;

console.log(a) // 2

function test() {
  var a = 3;
  var a = 4;
  console.log(a) // 4
}

test()

let 相關示例代碼:

if(false) {
  let a = 1;
  let a = 2; // SyntaxError: Identifier 'a' has already been declared
}
switch(index) {
  case 0:
    let a = 1;
  break;

  default:
    let a = 2; // SyntaxError: Identifier 'a' has already been declared
    break;
}

從上述示例中可以看出,let 聲明的重複性檢查是發生在詞法分析階段,也就是在代碼正式開始執行之前就會進行檢查。

(3)綁定全局對象

var 在全局環境聲明變量,會在全局對象里新建一個屬性,而 let 在全局環境聲明變量,則不會在全局對象里新建一個屬性。

示例代碼:

var foo = 'global'
let bar = 'global'

console.log(this.foo) // global
console.log(this.bar) // undefined

那這裏就一個疑問, let 在全局環境聲明變量不在全局對象的屬性中,那它是保存在哪的呢?

var foo = 'global'
let bar = 'global'

function test() {}

console.dir(test)

在Chrome瀏覽器的控制台中,通過執行上述代碼,查看 test 函數的作用域鏈,其結果如圖:

由上圖可知,let 在全局環境聲明變量 bar 保存在[[Scopes]][0]: Script這個變量對象的屬性中,而[[Scopes]][1]: Global就是我們常說的全局對象。

(4)變量提升與暫存死區

var 聲明變量存在變量提升,如何理解變量提升呢?

要解釋清楚這個,就要涉及到執行上下文和變量對象。

在 JavaScript 代碼運行時,解釋執行全局代碼、調用函數或使用 eval 函數執行一個字符串表達式都會創建並進入一個新的執行環境,而這個執行環境被稱之為執行上下文。因此執行上下文有三類:全局執行上下文、函數執行上下文、eval 函數執行上下文。

執行上下文可以理解為一個抽象的對象,如下圖:

Variable object:變量對象,用於存儲被定義在執行上下文中的變量 (variables) 和函數聲明 (function declarations) 。

Scope chain:作用域鏈,是一個對象列表 (list of objects) ,用以檢索上下文代碼中出現的標識符 (identifiers) 。

thisValue:this 指針,是一個與執行上下文相關的特殊對象,也被稱之為上下文對象。

一個執行上下文的生命周期可以分為三個階段:創建、執行、釋放。如下圖:

南投搬家公司費用,距離,噸數怎麼算?達人教你簡易估價知識!

搬家費用:依消費者運送距離、搬運樓層、有無電梯、步行距離、特殊地形、超重物品等計價因素後,評估每車次單

而所有使用 var 聲明的變量都會在執行上下文的創建階段時作為變量對象的屬性被創建並初始化,這樣才能保證在執行階段能通過標識符在變量對象里找到對應變量進行賦值操作等。

而用 var 聲明的變量構建變量對象時進行的操作如下:

  • 由名稱和對應值(undefined)組成一個變量對象的屬性被創建(創建並初始化)
  • 如果變量名稱跟已經聲明的形式參數或函數相同,則變量聲明不會幹擾已經存在的這類屬性。

上述過程就是我們所謂的“變量提升”,這也就能解釋為什麼變量可以在聲明之前使用,因為使用是在執行階段,而在此之前的創建階段就已經將聲明的變量添加到了變量對象中,所以執行階段通過標識符可以在變量對象中查找到,也就不會報錯。

示例代碼:

console.log(a) // undefined

var a = 1;

console.log(a) // 1

let 聲明變量存在暫存死區,如何理解暫存死區呢?

其實 let 也存在與 var 類似的“變量提升”過程,但與 var 不同的是其在執行上下文的創建階段,只會創建變量而不會被初始化(undefined),並且 ES6 規定了其初始化過程是在執行上下文的執行階段(即直到它們的定義被執行時才初始化),使用未被初始化的變量將會報錯。

let and const declarations define variables that are scoped to the running execution context’s LexicalEnvironment. The variables are created when their containing Lexical Environment is instantiated but may not be accessed in any way until the variable’s LexicalBinding is evaluated. A variable defined by a LexicalBinding with an Initializer is assigned the value of its Initializer’s AssignmentExpression when the LexicalBinding is evaluated, not when the variable is created. If a LexicalBinding in a let declaration does not have an Initializer the variable is assigned the value undefined when the LexicalBinding is evaluated.

在變量初始化前訪問該變量會導致 ReferenceError,因此從進入作用域創建變量,到變量開始可被訪問的一段時間(過程),就稱為暫存死區(Temporal Dead Zone)。

示例代碼 1:

console.log(bar); // undefined
console.log(foo); // ReferenceError: foo is not defined

var bar = 1;
let foo = 2;

示例代碼 2:

var foo = 33;
{
  let foo = (foo + 55); // ReferenceError: foo is not defined
}

注:首先,需要分清變量的創建、初始化、賦值是三個不同的過程。另外,從 ES5 開始用詞法環境(Lexical Environment)替代了 ES3 中的變量對象(Variable object)來管理靜態作用域,但作用是相同的。為了方便理解,上述講解中仍保留使用變量對象來進行描述。

小結

  1. var 聲明的變量在執行上下文創建階段就會被「創建」和「初始化」,因此對於執行階段來說,可以在聲明之前使用。

  2. let 聲明的變量在執行上下文創建階段只會被「創建」而不會被「初始化」,因此對於執行階段來說,如果在其定義執行前使用,相當於使用了未被初始化的變量,會報錯。

3.let 與 const 異同

const 與 let 很類似,都具有上面提到的 let 的特性,唯一區別就在於 const 聲明的是一個只讀變量,聲明之後不允許改變其值。因此,const 一旦聲明必須初始化,否則會報錯。

示例代碼:

let a;
const b = "constant"

a = "variable"
b = 'change' // TypeError: Assignment to constant variable

如何理解聲明之後不允許改變其值?

其實 const 其實保證的不是變量的值不變,而是保證變量指向的內存地址所保存的數據不允許改動(即棧內存在的值和地址)。

JavaScript 的數據類型分為兩類:原始值類型和對象(Object類型)。

對於原始值類型(undefined、null、true/false、number、string),值就保存在變量指向的那個內存地址(在棧中),因此 const 聲明的原始值類型變量等同於常量。

對於對象類型(object,array,function等),變量指向的內存地址其實是保存了一個指向實際數據的指針,所以 const 只能保證指針是不可修改的,至於指針指向的數據結構是無法保證其不能被修改的(在堆中)。

示例代碼:

const obj = {
  value: 1
}

obj.value = 2

console.log(obj) // { value: 2 }

obj = {} // TypeError: Assignment to constant variable

4.參考

var – JavaScript | MDN

let – JavaScript – MDN – Mozilla

const – JavaScript – MDN – Mozilla

深入理解JavaScript系列(12):變量對象(Variable Object)

ES6 let 與 const

詳解ES6暫存死區TDZ

嗨,你知道 let 和 const 嗎?

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※想知道購買電動車哪裡補助最多?台中電動車補助資訊懶人包彙整

節能減碳愛地球是景泰電動車的理念,是創立景泰電動車行的初衷,滿意態度更是服務客戶的最高品質,我們的成長來自於你的推薦。

初窺Ansible playbook_貨運

※回頭車貨運收費標準

宇安交通關係企業,自成立迄今,即秉持著「以誠待人」、「以實處事」的企業信念

Ansible是一個系列文章,我會盡量以通俗易懂、詼諧幽默的總結方式給大家呈現這些枯燥的知識點,讓學習變的有趣一些。
Ansible系列博文直達鏈接:Ansible入門系列

前言

在上一篇文章中說到Ansible有兩種玩法,一種是Ansible Ad-Hoc,另一種是就是這裏要說的playbook。playbook是Ansible進行配置管理的組件,雖然Ansible的日常Ad-Hoc命令功能很強大,能完成一些基本的配置管理工作,但是Ad-Hoc命令無法支撐複雜環境的配置管理工作。在我們實際使用Ansible的工作中,大部分時間都是在編寫playbook,接下來就重點說說如何玩轉這個playbook。

執行playbook命令

我們都是按照yaml語法規則來編寫playbook,至於yaml怎麼玩,後面的文章我會總結一下的。在我們按照要求編寫好了yaml文件后,如何來執行這個yaml文件呢?

Ansible提供了一個單獨的命令:ansible-playbook命令,我們可以通過這個命令來執行yaml腳本。常見的ansible-playbook的使用方法如下:

最簡單的使用方法:

ansible-playbook copyDemo.yaml

我們還可以使用以下命令查看輸出的細節:

ansible-playbook copyDemo.yaml --verbose

我們也可以使用以下命令查看該yaml腳本將影響的主機列表:

ansible-playbook copyDemo.yaml --list-hosts

還可以使用以下命令檢查yaml腳本語法是否正確:

ansible-playbook copyDemo.yaml --syntax-check

上面的幾種使用方法基本就涵蓋了我們日常工作中80%的場景了,剩餘的20%場景,比如并行、異步等,很少用到,等真正用到的時候再去查閱相關資料也來的及。而工作中,更多的時候,我們不是在編寫playbook,就是在編寫playbook的路上。所以,接下來我重點說說如何寫這個playbook,也就是playbook的基本語法。

playbook基本語法

最基本的playbook腳本分為三個部分:

  1. 在哪些機器上以什麼身份執行
  2. 執行的任務有哪些
  3. 善後任務有哪些

我們在編寫playbook腳本的時候,總是離不開上面的三個部分的。下面先來一個稍微有點複雜的playbook腳本,讓大家先有一個整體的認識。

---
- hosts: server1
  user: root
  vars:
    http_port: 80
    max_clients: 200

  tasks:
    - name: Write apache config file
      template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf
      notify:
        - restart apache
    - name: Ensure apache is running
      service: name=httpd state=started

  handlers:
    - name: restart apache
      service: name=httpd state=restarted

現在就對上述三部分稍作詳細總結。

主機和用戶

上面的yaml腳本,我們一開始就會看到hostsuservars,其中vars在後面的文章進行專門總結。而這裏的hostsuser就是表示我們這個yaml將要在哪些主機上用哪個用戶身份去操作。而這裏的深一層次的關係如下錶所示:

key 含義
hosts 為主機的IP,或者主機組名,或者關鍵字all
user 在遠程以哪個身份執行
become 切換成其他用戶身份執行,值為yes或者no
become_method 與become一起使用,值可以為sudo/su
become_user 與become一起使用,可以是root或者其它用戶名

在實際工作中,如果我們不指定user時,則默認使用連接遠程主機的用戶進行操作,如果指定了執行用戶而與ansible_ssh_user指定用戶不一致時,則需要開啟become操作,這裏的become配置與ansible.cfg中配置將相互配合完成工作,yaml中的become優先級高於ansible.cfg中配置中的優先級。

任務列表

任務列表是整個playbook的核心,對於任務列表,我們首先需要知道以下三點內容:

※智慧手機時代的來臨,RWD網頁設計為架站首選

網動結合了許多網際網路業界的菁英共同研發簡單易操作的架站工具,及時性的更新,為客戶創造出更多的網路商機。

  • 任務是從上到下順序執行的,如果中間發生錯誤,那麼整個playbook會中止;
  • 每一個任務都是對模塊的一次調用,只是使用不同的參數和變量而已;
  • 每一個任務最好有一個name屬性,這樣在執行yaml腳本時,可以看到執行進度信息。

對於任務的參數有兩種不同的寫法,我們在編寫yaml腳本時,可以按照自己的喜好進行選擇。

寫法一:

- name: Write apache config file
  template: src=/home/test1/httpd.j2 dest=/home/test2/httpd.conf

寫法二:

- name: Write apache config file
  template: 
    src: /home/test1/httpd.j2
    dest: /home/test2/httpd.conf

這兩種寫法都是OK的,我一般喜歡第二種寫法。

最後,對於任務我們還需要特別一個點,那就是任務的執行狀態。我們在執行Ansible Ad-Hoc或者ansible-playbook的時候,在輸出中都會有一個changed字段,比如:

192.168.1.3                : ok=2    changed=0    unreachable=0    failed=0  

或者

192.168.1.3                : ok=2    changed=1    unreachable=0    failed=0

這裏的這個changed就是人物的執行狀態,但是它為什麼一會是0,一會有是1呢?這就要說到Ansible中一個叫做“冪等性”的概念。

冪等性

冪等性是數學和計算機科學上一個常見的概念,多次執行產生的結果不會發生改變,這樣的特性就被成為冪等性。

大多數的Ansible模塊在設計時保證了冪等性,冪等性保證了Ansible腳本多次執行情況下的相同結果,盡可能的避免使用那些不能滿足冪等性的模塊。比如我們經常使用的shell模塊就是非冪等性的。

我們要明白Ansible是以“結果為導向的”,我們指定了一個“目標狀態”,Ansible會自動判斷“當前狀態”是否與“目標狀態”一致,如果一致,則不進行任何操作;如果不一致,那麼就將“當前狀態”變成“目標狀態”,這就是“冪等性”,“冪等性”可以保證我們重複的執行同一項操作時,得到的結果是一樣的。

那這個冪等性與上面的changed又有什麼關係呢?且聽我下面慢慢道來!

  • changed為false或者0時,表示Ansible沒有進行任何操作,沒有“改變什麼”;
  • changed為true或者大於0時,表示Ansible執行了操作,“當前狀態”已經被Ansible改變成了“目標狀態”。

copy這個模塊來舉例子說明,當我們準備將一個文件通過Ansible拷貝到遠程主機時,copy模塊首先檢查遠程是否已經存在了該文件,如果不存在,則把文件拷貝過去,返回changed為大於0;如果存在時,則開始比對兩個文件的md5值,如果md5值一致,則說明兩個文件是一樣的,則不需要拷貝,此時copy模塊則什麼都不幹,返回changed為0。

總結

通過三篇文章總結了Ansible中的常用模塊、Ansible Ad-Hoc和ansible-playbook的一些慣用用法,從我的實際學習經驗來說,學到這裏,你可以將這三塊內容結合起來使用了,至少可以在你們生產環境鼓搗一下了。生來就是折騰,更何況我們這麼拚命、努力的學習呢!

果凍想,認真玩技術的地方。

2019年5月18日,於內蒙古呼和浩特。

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

※評比南投搬家公司費用收費行情懶人包大公開

搬家價格與搬家費用透明合理,不亂收費。本公司提供下列三種搬家計費方案,由資深專業組長到府估價,替客戶量身規劃選擇最經濟節省的計費方式

Safari 導入延伸功能系統,目前開發者反應冷淡_網頁設計

※推薦評價好的iphone維修中心

擁有專業的維修技術團隊,同時聘請資深iphone手機維修專家,現場說明手機問題,快速修理,沒修好不收錢

在 WWDC 2020 時,Apple 宣布將在 Mac 版的Safari 14 中導入在 Chrome、Firefox 等瀏覽器上行之有年且受到用戶大大歡迎的的擴展應用 Web Extensions API,不過至今 6 個月過去了,由於 Apple 本身的遊戲規則獨立於其他平台之外,開發者的反應顯得冷淡,上架的新應用自然也不如預期。

Safari 導入擴展延伸系統,目前開發者反應冷淡

可在 MacOS Big Sur、Catalina 與 Mojave 上運行的 Safari 14,理論上可以為基於 JavaScript 的 Chrome、Firefox、Edge 等瀏覽器開發者提供大致上差不多的程式碼,並且轉換成 Mac 版 Safari 的擴展外掛。不過依照目前的進展來看,在 Mac APP Store 上所提供的 Safari 擴展中基本上都是 Safari 14 發表會之前的項目,僅有極少數新擴展出現。

Andrew Abrahamowicz 在 Library Extension 擴展外掛的開發上投注了 10 年的時間,是一款可以把當地圖書館書況在 Amazon 等網站的圖書賣場中顯示出來的外掛,Abrahamowicz 表示開發這款應用並不是他的本業,因此能夠付出的精力與時間也很有限,為此他入手了新的 M1 Mac 來進行後續的研究開發。支援一個新平台對開發者來說必須負擔很多額外的工作,除了必須利用 Xcode 設定之外,還必須處理 Apple 對延伸功能一些特定的安全限制,所以必須額外撰寫適用的程式碼,以便讓 Safari 版本能夠擁有和其他平台上一樣的功能。

從上面的例子可以看到許多癥結,像是大多數開發者都是業餘進行時間有限、因限定 Apple 硬體設備才能開發而卡住,以及對 Apple 開發工具的不熟悉等,都會成為開發者反應不如預期的原因。其中一個典型的例子就是 Beyond20 這款擴展,該擴展能夠將 D&D Beyond 角色表與 Roll20 等虛擬桌面服務連接起來,如果想要在 Mac 上使用,編輯只能切換到 Chrome 或 Firefox 瀏覽器。該應用項目負責人表示因為不是屬於 Chromium 系統而需要額外工作,加上自己平常並不使用 Safari ,所以不願意在 Safari 上架自家外掛。

目前看來,推動 Web Extensions API 是一項沒有盡頭的任務,在 APP Store 中已經出現極少數的外掛上架, 梭說可能會帶動其他擴展跟著行動,但大多數開發者似乎仍不為所動。國外媒體的意見是,如果最終 Apple 能夠將 Safari 擴展也推動到 iOS 或 iPadOS 上
,或許對於外掛的增長會更有效果。

台北網頁設計公司這麼多該如何選擇?

網動是一群專業、熱情、向前行的工作團隊,我們擁有靈活的組織與溝通的能力,能傾聽客戶聲音,激發創意的火花,呈現完美的作品

◎資料來源:Six colors

您也許會喜歡:

【推爆】終身$0月租 打電話只要1元/分

立達合法徵信社-讓您安心的選擇

網頁設計最專業,超強功能平台可客製化

窩窩以「數位行銷」「品牌經營」「網站與應用程式」「印刷品設計」等四大主軸,為每一位客戶客製建立行銷脈絡及洞燭市場先機。