1. 加載和執行
盡量將所有的<script>標簽放在</body>標簽之前,確保腳本執行前頁面已經完成了渲染,避免腳本的下載阻塞其他資源(例如圖片)的下載。
合并腳本,減少頁面中的<script>標簽
使用<script>標簽的defer和async屬性(兩者的區別見這里)
通過Javascript動態創建<script>標簽插入文檔來下載,其不會影響頁面其他進程
2.數據存取
由于作用域鏈的機制,訪問局部變量比訪問跨作用域變量更快,因此在函數中若要多次訪問跨作用域變量,則可以用局部變量保存。
避免使用with語句,其會延長作用域鏈
嵌套的對象成員會導致引擎搜索所有對象成員,避免使用嵌套,例如window.location.href
對象的屬性和方法在原型鏈的位置越深,訪問的速度也越慢
3.Dom編程
進行大段HTML更新時,推薦使用innerHTML,而不是DOM方法
HTML集合是一個與文檔中元素綁定的類數組對象,其長度隨著文檔中元素的增減而動態變化,因此避免在每次循環中直接讀取HTML集合的length,容易導致死循環
使用節點的children屬性,而不是childNodes屬性,前者訪問速度更快,且不包含空白文本和注釋節點。
瀏覽器的渲染過程包括構建DOM樹和渲染樹,當DOM元素的幾何屬性變化時,需要重新構造渲染樹,這一過程稱為“重排”,完成重排后,瀏覽器會重新繪制受影響的部分到屏幕中,這一過程稱為“重繪”。因此應該盡量合并多次對DOM的修改,或者先將元素脫離文檔流(display:none、文檔片段),應用修改后,再插入文檔中。
每次瀏覽器的重排時都會產生消耗,大多數瀏覽器會通過隊列化修改并批量執行來優化重排過程,可當訪問元素offsetTop、scrollTop、clientTop、getComputedStyle等一系列布局屬性時,會強制瀏覽器立即進行重排返回正確的值。因此不要在dom布局信息改變時,訪問這些布局屬性。
當修改同個元素多個Css屬性時,可以使用CssText屬性進行一次性修改樣式,減少瀏覽器重排和重繪的次數
當元素發生動畫時,可以使用絕對定位使其脫離文檔流,動畫結束后,再恢復定位。避免動畫過程中瀏覽器反復重排文檔流中的元素。
多使用事件委托,減少監聽事件
4.算法和流程控制
for循環和while循環性能差不多,除了for-in循環最慢(其要遍歷原型鏈)
循環中要減少對象成員及數組項的查詢次數,可以通過倒序循環提高性能
循環次數大于1000時,可運用Duff Devices減少迭代次數
switch比if-else快,但如果具有很多離散值時,可使用數組或對象來構建查找表
遞歸可能會造成調用棧溢出,可將其改為循環迭代
如果可以,對一些函數的計算結果進行緩存
5.字符串和正則表達式
進行大量字符串的連接時,+和+=效率比數組的join方法要高
當創建了一個正則表達式對象時,瀏覽器會驗證你的表達式,然后將其轉化為一個原生代碼程序,用戶執行匹配工作。當你將其賦值給變量時,可以避免重復執行該步驟。
當正則進入使用狀態時,首先要確定目標字符串的起始搜索位置(字符串的起始位置或正則表達式的lastIndex屬性),之后正則表達式會逐個檢查文本和正則模式,當一個特定的字元匹配失敗時,正則表達式會試著回溯到之前嘗試匹配的位置,然后嘗試其他路徑。如果正則表達式所有的可能路徑都沒有匹配到,其會將起始搜索位置下移一位,重新開始檢查。如果字符串的每個字符都經歷過檢查,沒有匹配成功,則宣布徹底失敗。
當正則表達式不那么具體時,例如.和[\s\S]等,很可能會出現回溯失控的情況,在js中可以應用預查模擬原子組(?=(pattern))\1來避免不必要的回溯。除此之外,嵌套的量詞,例如/(A+A+)+B/在匹配"AAAAAAAA"時可能會造成驚人的回溯,應盡量避免使用嵌套的量詞或使用預查模擬原子組消除回溯問題。
將復雜的正則表達式拆分為多個簡單的片段、正則以簡單、必需的字元開始、減少分支數量|,有助于提高匹配的效率。
setTimeout(function(){ process(todo.shift()); if (todo.length > 0) { setTimeout(arguments.callee, 25); } else { callback(); } })
setTimeout(function(){ let start = +new Date(); do { process(todo.shift()); } while(todo.length > 0 && (+new Date() - start) < 50) if (todo.length > 0) { setTimeout(arguments.callee, 25); } else { callback(); } })
WebWork
進行計算
Expires: Mon,28 Jul 2018 23:30:30 GMT
eval
、Function
進行雙重求值
Object
/Array
字面量定義,不要使用構造函數
if (i & 1) { className = 'odd'; } else { className = 'even'; }
Math
對象等
簡單來說,v-if 的初始化較快,但切換代價高;v-show 初始化慢,但切換成本低
都是動態顯示DOM元素
(1)手段:
v-if是動態的向DOM樹內添加或者刪除DOM元素;
v-show是通過設置DOM元素的display樣式屬性控制顯隱;
(2)編譯過程:
v-if切換有一個局部編譯/卸載的過程,切換過程中合適地銷毀和重建內部的事件監聽和子組件;
v-show只是簡單的基于css切換;
(3)編譯條件:
v-if是惰性的,如果初始條件為假,則什么也不做;只有在條件第一次變為真時才開始局部編譯(編譯被緩存?編譯被緩存后,然后再切換的時候進行局部卸載);
v-show是在任何條件下(首次條件是否為真)都被編譯,然后被緩存,而且DOM元素保留;
(4)性能消耗:
v-if有更高的切換消耗;
v-show有更高的初始渲染消耗;
(5)使用場景:
v-if適合運營條件不大可能改變;
v-show適合頻繁切換。
為了降低開發的復雜度,以后端為出發點,比如:Struts、SpringMVC 等框架的使用,就是后端的 MVC 時代;
以 SpringMVC 流程為例:
優點:
前后端職責很清晰: 前端工作在瀏覽器端,后端工作在服務端。清晰的分工,可以讓開發并行,測 試數據的模擬不難,前端可以本地開發。后端則可以專注于業務邏輯的處理,輸出 RESTful等接 口。
前端開發的復雜度可控: 前端代碼很重,但合理的分層,讓前端代碼能各司其職。這一塊蠻有意思 的,簡單如模板特性的選擇,就有很多很多講究。并非越強大越好,限制什么,留下哪些自由,代 碼應該如何組織,所有這一切設計,得花一本書的厚度去說明。
-部署相對獨立: 可以快速改進產品體驗
缺點:
代碼不能復用。比如后端依舊需要對數據做各種校驗,校驗邏輯無法復用瀏覽器端的代碼。如果可 以復用,那么后端的數據校驗可以相對簡單化。
全異步,對 SEO 不利。往往還需要服務端做同步渲染的降級方案。 性能并非最佳,特別是移動互聯網環境下。
SPA 不能滿足所有需求,依舊存在大量多頁面應用。URL Design 需要后端配合,前端無法完全掌控。
NodeJS 帶來的全棧時代
前端為主的 MV* 模式解決了很多很多問題,但如上所述,依舊存在不少不足之處。隨著 NodeJS 的興 起,JavaScript 開始有能力運行在服務端。這意味著可以有一種新的研發模式:
————————————————
版權聲明:本文為CSDN博主「叁有三分之一」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/iME_cho/article/details/105654633
塊級元素(inline):
塊級元素可以包含行內元素和其它塊級元素,且占據父元素的整個空間,可以設置 width 和 height 屬性,瀏覽器通常會在塊級元素前后另起一個新行。
常見塊級元素:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ width: 150px; height: 150px; background-color: cadetblue; } </style> </head> <body> <div>塊級元素1</div> <div>塊級元素2</div> </body> </html>
分析:
塊級元素的高和寬可以被修改,而且塊級元素會在一個塊級元素之后另起一行。
行級元素
行級元素(block):
一般情況下,行內元素只能包含內容或者其它行內元素,寬度和長度依據內容而定,不可以設置,可以和其它元素和平共處于一行。
常見行級元素:
a,b,strong,span,img,label,button,input,select,textarea
特點:
和相鄰的行內元素在一行上
高度和寬度無效,但是水平方向上的padding和margin可以設置,垂直方向上的無效
默認的寬度就是它本身的寬度
行內元素只能容納純文本或者是其他的行內元素(a標簽除外)
例如:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> span{ width: 150px; height: 150px; font-size: 40px; background-color: cadetblue; } </style> </head> <body> <span>行級元素1</span> <span>行級元素2</span> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> span{ width: 150px; height: 150px; font-size: 20px; background-color: cadetblue; display: inline-block; } </style> </head> <body> <span>以前我是行級元素,</span> <span>現在我只想做行內塊級元素。</span> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ width: 150px; height: 150px; font-size: 30px; background-color: cadetblue; display: inline; } </style> </head> <body> <div>我以前是塊級元素,</div> <div>現在我是行級元素!</div> </body> </html>
分析:
在VSC中,修改寬高的代碼已經出現了波浪線,證明他是錯誤的,所以現在的div
已經變成了行級元素。
————————————————
版權聲明:本文為CSDN博主「董小宇」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/lolly1023/article/details/105715892
其實VSCode編輯器本身自帶了一個功能(Interactive Editor Playground :可以讓你快速了解VSCode的特性,并且是可以交互的),
但很可惜它的內容是全英文的(將VSCode設置為中文也沒用哦~),
我將每一部分截圖下來,并為你說明關鍵內容,教你學會使用 Interactive Editor Playground
還有一些顯而易見的特性,我不會再用文字敘述一遍(它們都是潛移默化的)
在下文中會涉及到大量快捷鍵的介紹,如果看不懂快捷鍵請自行百度
鼠標 = 文本光標 = 光標
本文成于2020年4月22日,隨著VSCode的版本更迭,此部分內容可能會略有差異(小更改不影響觀看,有較大影響的更新請在評論區告之,我會及時更新的)
打開VSCode > Help > Interactive Playground
你將會打開 Interactive Editor Playground 頁面
VS代碼中的核心編輯器包含許多特性。此頁高亮顯示了10個特性,每個特性介紹中都提供了代碼行供你編輯
接下來的10行內容(你可以理解為目錄,對應10個特性)
多光標編輯(Multi-Cursor Editing)- 選擇一塊區域,選擇所有匹配項,添加其余光標等
智能感應(intelliSense)- 獲取代碼和外部模塊的代碼幫助和參數建議
行操作(Line Actions )- 快速移動行以重新排序代碼
重命名重構(Rename Refactoring)- 快速重命名代碼庫中的符號(比如變量名、函數名)
格式化(Formatting)- 使用內置文檔和選擇格式使代碼看起來很棒
代碼折疊(Code Folding) - 通過折疊其他代碼區域,關注代碼中最相關的部分
錯誤和警告(Errors and Warnings)- 寫代碼時請參閱錯誤和警告
片段(Snippets)- 花更少的時間輸入片段
Emmet - 只需要敲一行代碼就能生成你想要的完整HTML結構等(極大方便前端開發)
JavaScript Type Checking- 使用零配置的TypeScript對JavaScript文件執行類型檢查。
Multi-Cursor Editing
使用多光標編輯可以同時編輯文檔的多個部分,極大地提高了工作效率
框式選擇
鍵盤同時按下 Shift + DownArrow(下鍵)、Shift + RightArrow(右鍵)、Shift + UpArrow(上鍵)、Shift + LeftArrow(左鍵) 的任意組合可選擇文本塊
也可以用鼠標選擇文本時按 Shift + Alt 鍵
或使用鼠標中鍵拖動選擇(可用性很高)
添加光標
按 Ctrl + Alt + UpArrow 在行上方添加新光標
或按 Ctrl + Alt + DownArrow 在行下方添加新光標
您也可以使用鼠標和 Alt + Click 在任何地方添加光標(可用性很高)
在所有出現的字符串上創建光標
選擇字符串的一個實例,例如我用鼠標選中所有background,然后按 Ctrl + Shift + L,文本中所有的background都將被選中(可用性很高)
IntelliSense
Visual Studio Code 預裝了強大的JavaScript和TypeScript智能感知。
在代碼示例中,將文本光標放在錯誤下劃線的上面,會自動調用IntelliSense
這只是智能提示的冰山一角,還有懸停在函數名上可以看到參數及其注釋(如果有)等等,它會潛移默化的帶給你極大幫助
其他語言在安裝對應插件后,會附帶對應語言的IntelliSense
Line Actions
分別使用 Shift + Alt + DownArrow 或 Shift + Alt + UpArrow 復制光標所在行并將其插入當前光標位置的上方或下方
分別使用 Alt + UpArrow 和 Alt + DownArrow 向上或向下移動選定行(可用性很高)
用 Ctrl + Shift + K 刪除整行(可用性很高)
通過按 Ctrl + / 來注釋掉光標所在行、切換注釋(可用性很高)
Rename Refactoring
重命名符號(如函數名或變量名)
重命名操作將在項目中的所有文件中發生(可用性很高)
代碼如果沒有良好的編寫格式,閱讀起來是一個折磨
Formatting可以解決編寫格式問題:無論你的代碼的格式寫的有多么糟糕,它可以將代碼格式化為閱讀性良好的格式
格式化整個文檔 Shift + Alt + F (可用性很高)
格式化當前行 Ctrl + K Ctrl + F(即先按Ctrl,再按K,最后按F)
鼠標右鍵 > Format Document (格式化整個文檔)
將格式化操作設置為自動化(保存時自動格式化整個文檔):Ctrl + , 輸入 editor.formatOnSave
鼠標操作,自己嘗試一下,秒懂
快捷鍵:
折疊代碼段是基于基于縮進
錯誤和警告將在你出現錯誤時,高亮該代碼行
在代碼示例中可以看到許多語法錯誤(如果沒有,請你隨便修改它,讓它出現錯誤)
按F8鍵可以按順序在錯誤之間導航,并查看詳細的錯誤消息(可用性很高)
Snippets
通過使用代碼片段,可以大大加快編輯速度
在代碼編輯區,你可以嘗試輸入try并從建議列表中選擇try catch,
然后按Tab鍵或者Enter,創建try->catch塊
你的光標將放在文本error上,以便編輯。如果存在多個參數,請按Tab鍵跳轉到該參數。
Emmet
Emmet將代碼片段的概念提升到了一個全新的層次(前端開發的大寶貝)
你可以鍵入類似Css的可動態解析表達式,并根據在abrevision中鍵入的內容生成輸出
比如說:
然后Enter
————————————————
版權聲明:本文為CSDN博主「索兒呀」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Zhangguohao666/article/details/105676173
最近身邊的一些小伙伴,總會遇見B端設計工作,對于這種偏后臺設計的B端設計,總會有大量的表單設計需要做,結合以前自己也有過不少表單設計的工作,在這里給大家分享一下自己對于PC端表單設計的研究,聊一聊表單在PC端中的運用。
商業離不開數據,而數據總會依賴不同的表現形式,不管是word文檔,還是數據可視化,都是瀏覽者通過表現形式來對數據進行閱讀和分析,因此表單的設計就是一種表現形式,我們將捋一捋如何通過表單更好的讓用戶閱讀順暢、操作方便、總而言之就是更好用啦。
無線分割:顧名思義,列表的信息之間正常情況下沒有分割線等方法來分隔,僅僅是用間距來分隔開內容。好處是元素更少,畫面更簡潔,但是視覺可能就沒那么清晰了,使用的出場率一般。
有線分割:同樣字面意思,就是通過簡單的分割線來分割列表中的信息,讓視線左右移動的時候更加穩定、輕松,在表單設計中使用的出場率非常高。
斑馬線:通過深淺交替的色塊,以及色塊產生的對比來分隔列表中的信息,深淺深淺的循環就好像斑馬線,使用時是通過色塊產生對比,所以也可以使用帶有適量飽和度的色塊來區分,占頁面面積比例較大,適當用色可以使得畫面更加活潑、豐滿,斑馬線也是出場率極高的一種展現形式。
斑馬線+分割線:很容易理解,就是斑馬線風格+分割線的結合,用色塊區分的同時又加了分割線,信息之間的區分對比更加強烈,但是畫面層級就多了一些,沒有其他的看起來簡潔,使用出場率也一般。
卡片式:跟卡片式風格其他設計一樣,分別用懸浮的色塊來區分,間隔的地方是背景色,分隔的力度比較強,內容區分的很清晰,弊端是更加占畫面的位置,尤其在信息很多列的時候,會增加大量的高度,用戶需要更多時間進行下翻的操作。使用出場率相對其他形式來說稍低。
場景:用戶需要閱讀大量的表單數據,且需要頻繁的翻頁、跳轉。
如圖,左下角可以設置界面中每頁顯示信息數量的多少,用戶可以根據自己的需要自由設置,當瀏覽的數據較多的時候,不再需要頻繁點擊下一頁來瀏覽信息,只需把每頁顯示的數量調高,如此便減少了大量的操作次數。
像這樣允許用戶可以自由編輯來改進體驗的方式還有很多,比如可以設置顯示密度,就是以一樣的方式自由調整信息與分割線的間距。除了行間距,有的可以自由設置每一列的列間距,用戶可以根據自己的習慣來設置。
場景:用戶需要瀏覽大量的數據,并需要對數據反復進行計算、分析。
在使用大量的文字列表展示數據的同時,使用數據可視化加以配合,用戶可以更好的預覽到數據的大致情況,又可以在列表表單中閱讀到詳細的數據。
場景:用戶想根據某種條件的大小排序,來先后閱讀數據。
通過點擊第一排小標題行,可以選擇不同的方式調整信息的排序方式,就和電商商品排序一樣,可以選擇金額高到低或者低到高排序,也可以選擇別的方式進行排序,從而更快找到自己所需要的內容。
場景:從一大堆混雜的數據當中,尋找符合條件的自己所需要的數據。
添加篩選功能,過濾掉自己不想瀏覽的內容,通過條件篩選,更快的更的找到自己想要的內容、縮小查找范圍、減少達到目的所花的時間。一般通過下拉按鈕的形式選擇不同的條件來進行篩選過濾。
場景:已知列表中某信息的名稱關鍵字,想從大量混雜的列表中快速找到。
跟篩選過濾一樣,添加關鍵字搜索功能,用戶提供部分關鍵字,可通過關鍵字查詢,最快最的找到想要的那一條內容。一般該目標內容是用戶已知的,有時候是針對性的。
場景:精簡設計風格的界面,不想界面中內容過于繁多。
如圖,鼠標懸停在哪一行,哪一行才會顯示該列表后面的操作按鈕,好處是減少了視覺干擾,能更快的找到捕捉到操作位置,弊端是用戶不進行交互的時候無法發現操作按鈕如何出現。
場景:想快速獲取列表中某信息的其他附屬內容。
如圖,點擊某一行后,展現該行的一些附屬信息。可以不用跳轉頁面而進一步了解該行信息的詳情。
場景:在瀏覽列表的同時,需要頻繁的對列表中的信息進行編輯。
用戶可以直接對列表信息進行修改、編輯,省去了跳轉再編輯的麻煩步驟,更節約時間,用戶操作起來更加方便。
場景:需要充分了解列表中不同信息的詳細說明,頻繁跳轉又過于麻煩。
和可展開列表的作用類似,但是可展開列表顯示的內容有限,快速預覽的功能可以用側彈框的方式、彈出對話窗口的方式、以及其他方式對選中的內容直接展示詳細信息。用戶不需要跳轉至詳情頁就可以了解到大量信息,省去繁瑣的交互流程。不再需要頻繁的跳轉到詳情-返回-跳轉到另一個詳情-返回-跳轉-返回。使用快速預覽的功能就可以很好的解決這一問題。
(PS:彈出對話窗口的方式,可以同時彈出好幾項列表的詳情信息進行對比,但是側彈框因為高度優勢,可以展現更多內容)
場景:列表中每條內容顯示信息參數過多,且很多不想瀏覽。
自定義列表功能是用戶可以自由設置每行信息參數的內容,比如我不想列表中顯示金額這一項,就可以刪除,想要的時候可以添加回來,這樣用戶可以保留自己想要的那幾項內容,可以更快更方便的閱讀到自己關心的那幾項參數,節省了用戶的有效時間。
場景:列表橫向或者縱向過多,下翻或橫拉的時候標題頭被隱藏,不知道自己當前瀏覽到的參數屬于哪一項。
交互過程中,可以把第一排重要的東西固定,列表內容翻動的同時,第一排仍然在原位不移動而且覆蓋列表中的其他信息,很多自帶的框架都是這樣的形式,使用的出場率也是非常高,這樣用戶可以隨時查看到自己看到的內容是屬于哪一項屬性,或者是屬于哪一條信息,可以是橫向固定,也可以固定豎直的第一排標題,也可以固定最后一塊操作點擊區域,具體如何固定、是否固定,根據整體的需求來選擇。
通常表單都是大量的文字,大多數的文字高度都在該行高度的三分之一左右。過于緊密用戶瀏覽不順暢,過于分開顯得畫面過于松散,不同的分割方式,間距也會有所不同。
其實上面的每一條都是一個小總結,每一條在大部分的列表中都可以用到,主要還是根據實際需求來運用這幾點,比如分割的方式根據主體風格來搭配,不要為了設計而設計盲目運用,畢竟設計都是以內容為主,尤其是表單設計,本身就是更好的表達內容。
本文發布于人人都是產品經理。
ES6 允許按照一定模式,從數組和對象中提取值,對變量進行賦值,這被稱為解構(Destructuring)
本質上,這種寫法屬于“模式匹配”,只要等號兩邊的模式相同,左邊的變量就會被賦予對應的值
如果解構不成功,變量的值就等于undefined
解構賦值的規則是,只要等號右邊的值不是對象或數組,就先將其轉為對象。由于undefined和null無法轉為對象,所以對它們進行解構賦值,都會報錯、
交換變量的值
例如:let x=1,y=2;[x,y] = [y,x]
從函數返回多個值
函數只能返回一個值,如果要返回多個值,只能將它們放在數組或對象里返回。有了解構賦值,取出這些值就非常方便
函數參數的定義
解構賦值可以方便地將一組參數與變量名對應起來
提取 JSON 數據,很多接口數據只需要其中某部分
例如aa.axios.get(res=>{let {data:result}=res;}),則res.data.result = result了
函數參數的默認值
指定參數的默認值,就避免了在函數體內部再寫var foo = config.foo || ‘default foo’;這樣的語句
遍歷 Map 結構
Map 結構原生支持 Iterator 接口,配合變量的解構賦值,獲取鍵名和鍵值就非常方便
輸入模塊的指定方法
加載模塊時,往往需要指定輸入哪些方法。解構賦值使得輸入語句非常清晰。* const { SourceMapConsumer, SourceNode } = require(“source-map”);
左右兩側數據解構須得吻合,或者等號左邊的模式,只匹配一部分的等號右邊的數組(屬于不完全解構)
特殊情況使用…擴展運算符,無值是空數組
左右兩邊等式的性質要相同,等號的右邊不是數組(或者嚴格地說,不是可遍歷的結構),那么將會報錯,只要某種數據結構具有 Iterator
接口,都可以采用數組形式的解構賦值,例如Set結構
解構賦值允許指定默認值,當一個數組成員嚴格等于undefined,默認值才會生效,否則取賦值的值;如果默認值是一個表達式,那么這個表達式是惰性求值的,即只有在用到的時候,才會求值;默認值可以引用解構賦值的其他變量,但該變量必須已經聲明
// 數組的解構賦值 let [a,b] = [1,2]; console.log([a,b],a);//[1, 2] 1 let [aa] = [11,22]; console.log(aa)//11 let [aaa,bbb] = [111]; console.log(aaa,bbb)//111 undefined let [head, ...tail] = [1, 2, 3, 4]; console.log(head,tail)//1,[2,3,4] let [x, y, ...z] = ['a']; console.log(x,y,z)//a undefined [] // 等號右邊不是數組會報錯 // let [ab] = 121; // conosle.log(ab)//TypeError: 121 is not iterable // let [abc] = {} // conosle.log(abc)//TypeError: {} is not iterable // 默認值賦值 let [zz = 1] = [undefined]; console.log(zz)//1 let [zzz = 1] = [null]; console.log(zzz)//null let [foo = true] = []; console.log(foo)// true let [xxx, yyy = 'b'] = ['a']; console.log(xxx,yyy)//a,b let [xxxx, yyyy = 'b'] = ['a', undefined]; console.log(xxxx,yyyy)//a,b function f() { console.log('aaa'); } let [xx = f()] = [1]; console.log(xx)//1 let [qq=ww,ww=11] = [23,44]; console.log(qq,ww)//23,44,因為ww申明比qq晚所以是undefined;
2、對象的解構賦值
對象的解構賦值的內部機制,是先找到同名屬性,然后再賦給對應的變量。真正被賦值的是后者,而不是前者
數組是按照位置區分,對象則是按照鍵名區分的,同樣的解構失敗則為undefine
可將已有方法對象解構賦值
嵌套賦值,注意是變量是否被賦值是模式還是鍵值
對象的解構賦值可以取到繼承的屬性
如果要將一個已經聲明的變量用于解構賦值,必須非常小心
let xx; // {xx} = {xx: 1}這樣會報錯,
解構賦值允許等號左邊的模式之中,不放置任何變量名。因此,可以寫出非常古怪的賦值表達式
({} = [true, false]);//可執行
由于數組本質是特殊的對象,因此可以對數組進行對象屬性的解構
objFuc(){ // 對象解構賦值 let {b,a} = {a:1} console.log(a,b)//1 undefined // 已有對象解構賦值 let { sin, cos } = Math;//將Math對象的對數、正弦、余弦三個方法,賦值到對應的變量上 console.log(sin);//log() { [native code] } const { log } = console; log('hello') // hello // let { foo: baz } = { foo: 'aaa', bar: 'bbb' }; console.log(baz);//aaa // 嵌套賦值 let obj = { p: [ 'Hello', { y: 'World' } ] }; let { p,p:[x, { y }] } = obj; console.log(x,y,p)//Hello World p: ['Hello',{ y: 'World' }] //繼承賦值 const obj1 = {}; const obj2 = { foo: 'bar' }; Object.setPrototypeOf(obj1, obj2);//obj1繼承obj2 const { foo } = obj1; console.log(foo) // "bar" // 默認值 // 錯誤的寫法 let xx; // {xx} = {xx: 1};// SyntaxError: syntax error,Uncaught SyntaxError: Unexpected token '=' ({xx} = {xx: 1});//正確寫法 console.log(xx) // 古怪的,等式左邊可為空 // ({} = [true, false]); // 對象可解構數組 let arr = [1, 2, 3]; let {0 : first, [arr.length - 1] : last} = arr; console.log(first,last)//1 3 },
strFuc(){ // str:'yan_yan' let [a,b,c,d,e,f,g] = this.str; console.log(a,b,c,d,e,f,g)//y a n _ y a n // 對數組屬性解構賦值 let {length} = this.str; console.log(length)//7 },
4、數值和布爾值的解構賦值
let {toString: s} = 123; console.log(s === Number.prototype.toString,s)//true ? toString() { [native code] } let {toString: ss} = true; console.log(ss === Boolean.prototype.toString,ss)// true ? toString() { [native code] } // 右側必須是數組或對象,undefined和null無法轉為對象,所以對它們進行解構賦值,都會報錯 // let { prop: x } = undefined; // TypeError // let { prop: y } = null; // TypeError
5、函數參數的解構賦值
// 函數的解構賦值可使用默認值,注意默認值是指實參的默認值而不是形參的默認值 function move({x=1, y=1}={}) { return [x, y]; } function move1({x, y} = { x: 0, y: 0 }) { return [x, y]; } function move2({x, y=1} = { x: 0, y: 0 }) { return [x, y]; } console.log(move({x: 3, y: 8})); // [3, 8] console.log(move({x: 3})); // [3, 1] console.log(move({})); // [1, 1] console.log(move()); // [1,1] console.log(move1({x: 3, y: 8})); // [3, 8] console.log(move1({x: 3})); // [3, 1] console.log(move1({})); // [undefined, 1] console.log(move1()); // [0,0] console.log(move2({x: 3, y: 8})); // [3, 8] console.log(move2({x: 3})); // [3, 1] console.log(move2({})); // [undefined, 1] console.log(move2()); // [0,0]
6、圓括號問題 解構賦值雖然很方便,但是解析起來并不容易。對于編譯器來說,一個式子到底是模式,還是表達式,沒有辦法從一開始就知道,必須解析到(或解析不到)等號才能知道。 由此帶來的問題是,如果模式中出現圓括號怎么處理。ES6 的規則是,只要有可能導致解構的歧義,就不得使用圓括號。 可以使用圓括號的情況只有一種:賦值語句的非模式部分,可以使用圓括號 總結: 不管是哪一類的解構賦值,等式右邊的數據必須是對象形式(數組也是一種對象形式) ———————————————— 版權聲明:本文為CSDN博主「Yan_an_n」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。 原文鏈接:https://blog.csdn.net/weixin_44258964/article/details/105643553
目錄
HTTP協議
HTTP請求:
HTTP響應:
會話與會話狀態:
Cookie
Session
Cookie和Session的區別
HTTP協議
HTTP請求:
Post /test.php HTTP/1.1 //請求行以一個方法符號開頭,以空格分開,后面跟著請求的URI和協議的版本
Host: www.test.com //請求頭
User-agent:mozilla/5.0(windows NT 6.1: rv: 15.0)
Gecko/20100101 firefox15.0
//空白行,代表請求頭結束
Username=admin&passwd=admin //請求正文
HTTP請求方法
GET 請求獲取Request-URI所標識的資源
POST 在Request-URI所標識的資源后附加新的數據
HEAD 請求獲取由Request-URI所標識的資源的響應消息報頭
PUT 請求服務器存儲一個資源,并用Request-URI作為其標識
常用的為GET和POST;GET和POST的區別:
GET提交的內容會直接顯示在URL中,私密性較差,可以用于顯示一些公共資源;但是GET效率會比較高。
POST不會將內容顯示在URL中,可以用于提交一些敏感數據,例如用戶名或密碼。
HTTP響應:
HTTP/1.1 200 OK //響應行由協議版本號,響應狀態碼和文本描述組成
Data:sun,15 nov 2018 11:02:04 GMT //響應頭
Server:bfe/1.0.8.9
……
Connection: keep-alive
//空白行,代表響應頭結束
<html>
</html><title>index.heml</title> //響應正文
HTTP的狀態碼:
狀態代碼由三位數字組成,第一個數字定義了響應的類別,且有五種可能取值。
1xx:指示信息 —— 表示請求已接收,繼續處理。
2xx:成功 —— 表示請求已被成功接收、理解、接受。
3xx:重定向 —— 要完成請求必須進行更進一步的操作。
4xx:客戶端錯誤 —— 請求有語法錯誤或請求無法實現。
5xx:服務器端錯誤 —— 服務器未能實現合法的請求。
常見狀態代碼、狀態描述的說明如下。
200 OK:客戶端請求成功。
400 Bad Request:客戶端請求有語法錯誤,不能被服務器所理解。
401 Unauthorized:請求未經授權,這個狀態代碼必須和 WWW-Authenticate 報頭域一起使用。
403 Forbidden:服務器收到請求,但是拒絕提供服務。
404 Not Found:請求資源不存在,舉個例子:輸入了錯誤的URL。
500 Internal Server Error:服務器發生不可預期的錯誤。
503 Server Unavailable:服務器當前不能處理客戶端的請求,一段時間后可能恢復正常。
會話與會話狀態:
Web中的會話是指一個客戶端瀏覽器與web服務器之間連續發生一系列請求和響應過程。會話狀態是指在會話過程中產生的狀態信息;借助會話狀態,web服務器能夠把屬于同一會話中的一系列的請求和響應關聯起來。
Cookie
概述
Cookie是一種在客戶端保持HTTP狀態信息的技術,它好比商場發放的優惠卡。在瀏覽器訪問Web服務器的某個資源時,由Web服務器在在HTTP響應頭中附帶傳送給瀏覽器一片數據,web服務器傳送給各個客戶端瀏覽器的數據是可以各不相同的。
一旦Web瀏覽器保存了某個Cookie,那么它在以后每次訪問該Web服務器是都應在HTTP請求頭中將這個Cookie回傳個Web服務器。Web服務器通過在HTTP響應消息中增加Set-Cookie響應頭字段將CooKie信息發送給瀏覽器,瀏覽器則通過在HTTP請求消息中增加Cookie請求頭字段將Cookie回傳給Web服務器。
一個Cookie只能標識一種信息,它至少含有一個標識該消息的名稱(NAME)和和設置值(VALUE)。一個Web瀏覽器也可以存儲多個Web站點提供的Cookie。瀏覽器一般只允許存放300個Cookie,每個站點最多存放20個Cookie,每個Cookie的大小限制為4KB。
傳送示意圖
特點
存儲于瀏覽器頭部/傳輸與HTTP頭部,寫時帶屬性,讀時無屬性。由三元【name,domain,path】唯一確定Cookie。
Set-Cookie2響應頭字段
Set-Cookie2頭字段用于指定WEB服務器向客戶端傳送的Cookie內容,但是按照Netscape規范實現Cookie功能的WEB服務器, 使用的是Set-Cookie頭字段,兩者的語法和作用類似。Set-Cookie2頭字段中設置的cookie內容是具有一定格式的字符串,它必須以Cookie的名稱和設置值開頭,格式為"名稱=值”,后面可以加上0個或多個以分號(;) 和空格分隔的其它可選屬性,屬性格式一般為 "屬性名=值”。
除了“名稱=值”對必須位于最前面外,其他的可選屬性可以任意。Cookie的名稱只能由普通的英文ASCII字符組成,瀏覽器不用關心和理解Cookie的值部分的意義和格式,只要WEB服務器能理解值部分的意義就行。大多數現有的WEB服務器都是采用某種編碼方式將值部分的內容編碼成可打印的ASCII字符,RFC 2965規范中沒有明確限定編碼方式。
舉例: Set-Cookie2: user-hello; Version=1; Path=/
Cookie請求頭字段
Cookie請求頭字段中的每個Cookie之間用逗號(,)或分號(;)分隔。在Cookie請求字段中除了必須有“名稱=值”的設置外,還可以有Version、path、domain、port等屬性;在Version、path、domain、port等屬性名之前,都要增加一個“$”字符作為前綴。Version屬性只能出現一次,且要位于Cookie請求頭字段設置值的最前面,如果需要設置某個Cookie信息的Path、Domain、Port等屬性,它們必須位于該Cookie信息的“名稱=值”設置之后。
瀏覽器使用Cookie請求頭字段將Cookie信息會送給Web服務器;多個Cookie信息通過一個Cookie請求頭字段會送給Web服務器。
瀏覽器會根據下面幾個規則決定是否發送某個Cookie信息:
1、請求主機名是否與某個存儲的Cookie的Domain屬性匹配
2、請求的端口號是否在該Cookie的Port屬性列表中
3、請求的資源路徑是否在該Cookie的Path屬性指定的目錄及子目錄中
4、該Cookie的有效期是否已過
Path屬性的指向子目錄的Cookie排在Path屬性指向父目錄的Cookie之前
舉例: Cookie: $Version=1; Course=Java; $Path=/hello/lesson;Course=vc; $Path=/hello
Cookie的安全屬性
secure屬性
當設置為true時,表示創建的Cookie會被以安全的形式向服務器傳輸,也就是只能在HTTPS連接中被瀏覽器傳遞到服務器端進行會話驗證,如果是HTTP連接則不會傳遞該信息,所以不會被竊取到Cookie的具體內容。
HttpOnly屬性
如果在Cookie中設置了"HttpOnly"屬性,那么通過程序(JS腳本、Applet等)將無法讀取到Cookie信息,這樣能有效的防止XSS攻擊。
總結:secure屬性 是防止信息在傳遞的過程中被監聽捕獲后信息泄漏,HttpOnly屬性的目的是防止程序獲取cookie后進行攻擊這兩個屬性并不能解決cookie在本機出現的信息泄漏的問題(FireFox的插件FireBug能直接看到cookie的相關信息)。
Session
使用Cookie和附加URL參數都可以將上一-次請求的狀態信息傳遞到下一次請求中,但是如果傳遞的狀態信息較多,將極大降低網絡傳輸效率和增大服務器端程序處理的難度。
概述
Session技術是一種將會話狀態保存在服務器端的技術,它可以比喻成是醫院發放給病人的病歷卡和醫院為每個病人保留的病歷檔案的結合方式。客戶端需要接收、記憶和回送Session的會話標識號,Session可以且通常是借助Cookie來傳遞會話標識號。
Session的跟蹤機制
HttpSession對象是保持會話狀態信息的存儲結構,一個客戶端在WEB服務器端對應一個各自的HttpSession對象。WEB服務器并不會在客戶端開始訪問它時就創建HttpSession對象,只有客戶端訪問某個能與客戶端開啟會話的服務端程序時,WEB應用程序才會創建一個與該客戶端對應的HttpSession對象。WEB服務器為HttpSession對象分配一個獨一無的會話標識號, 然后在響應消息中將這個會話標識號傳遞給客戶端。客戶端需要記住會話標識號,并在后續的每次訪問請求中都把這個會話標識號傳送給WEB服務器,WEB服務器端程序依據回傳的會話標識號就知道這次請求是哪個客戶端發出的,從而選擇與之對應的HttpSession對象。
WEB應用程序創建了與某個客戶端對應的HttpSession對象后,只要沒有超出一個限定的空閑時間段,HttpSession對象就駐留在WEB服務器內存之中,該客戶端此后訪問任意的Servlet程序時,它們都使用與客戶端對應的那個已存在的HttpSession對象。
Session是實現網上商城的購物車的最佳方案,存儲在某個客戶Session中的一個集合對象就可充當該客戶的一個購物車。
超時管理
WEB服務器無法判斷當前的客戶端瀏覽器是否還會繼續訪問,也無法檢測客戶端瀏覽器是否關閉,所以,即使客戶已經離開或關閉了瀏覽器,WEB服務器還要保留與之對應的HttpSession對象。隨著時間的推移而不斷增加新的訪問客戶端,WEB服務器內存中將會因此積累起大量的不再被使用的HttpSession對象,并將最終導致服務器內存耗盡。WEB服務器采用“超時限制”的辦法來判斷客戶端是否還在繼續訪問如果某個客戶端在一定的時間之 內沒有發出后續請求,WEB服務器則認為客戶端已經停止了活動,結束與該客戶端的會話并將與之對應的HttpSession對象變成垃圾。
如果客戶端瀏覽器超時后再次發出訪問請求,Web服務器則認為這是一個新的會話開始,將為之創建新的Httpsession對象和分配新的會話標識號。
利用Cookie實現Session的跟蹤
如果WEB服務器處理某個訪問請求時創建了新的HttpSession對象,它將把會話標識號作為一個Cookie項加入到響應消息中,通常情況下,瀏覽器在隨后發出的訪問請求中又將會話標識號以Cookie的形式回傳給WEB服務器。WEB服務器端程序依據回傳的會話標識號就知道以前已經為該客戶端創建了HttpSession對象,不必再為該客戶端創建新的HttpSession對象,而是直接使用與該會話標識號匹配的HttpSession對象,通過這種方式就實現了對同一個客戶端的會話狀態的跟蹤。
利用URL重寫實現Session跟蹤
Servlet規范中引入了一種補充的會話管理機制,它允許不支持Cookie的瀏覽器也可以與WEB服務器保持連續的會話。這種補充機制要求在響應消息的實體內容中必須包含下一 次請求的超鏈接,并將會話標識號作為超鏈接的URL地址的一個特殊參數。將會話標識號以參數形式附加在超鏈接的URL地址后面的技術稱為URL重寫。 如果在瀏覽器不支持Cookie或者關閉了Cookie功能的情況下,WEB服務器還要能夠與瀏覽器實現有狀態的會話,就必須對所有能被客戶端訪問的請求路徑(包括超鏈接、form表單的action屬性設置和重定向的URL)進行URL重寫。
Cookie和Session的區別
session和cookies同樣都是針對單獨用戶的變量(或者說是對象好像更合適點),不同的用戶在訪問網站的時候都會擁有各自的session或者cookies,不同用戶之間互不干擾。
他們的不同點是:
1,存儲位置不同
session在服務器端存儲,比較安全,但是如果session較多則會影響性能
cookies在客戶端存儲,存在較大的安全隱患
2,生命周期不同
session生命周期在指定的時間(如20分鐘) 到了之后會結束,不到指定的時間,也會隨著瀏覽器進程的結束而結束。
cookies默認情況下也隨著瀏覽器進程結束而結束,但如果手動指定時間,則不受瀏覽器進程結束的影響。
總結:簡而言之,兩者都是保存了用戶操作的歷史信息,但是存在的地方不同;而且session和cookie的目的相同,都是為了克服HTTP協議無狀態的缺陷,但是完成方法不同。Session通過cookie在客戶端保存session id,將用戶的其他會話消息保存在服務端的session對象中;而cookie需要將所有信息都保存在客戶端,因此存在著一定的安全隱患,例如本地Cookie中可能保存著用戶名和密碼,容易泄露。
————————————————
版權聲明:本文為CSDN博主「悲觀的樂觀主義者」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_43997530/article/details/105650267
his是一個關鍵字,表示執行當前函數的對象
function fn(){
console.log(this); //window
console.log(typeof this); //object
}
fn();
- 嚴格模式下,this指向undefiend
"use strict";
function fn(){
console.log(this); //undefined
}
fn();
藍藍設計的小編 http://paul-jarrel.com