你盼世界,我盼望你無bug
。Hello 你們好!我是霖呆呆!css
呆呆每週都會分享七道前端題給你們,系列名稱就是「DD每週七題」。html
系列的形式主要是:3道JavaScript
+ 2道HTML
+ 2道CSS
,幫助咱們你們一塊兒鞏固前端基礎。前端
全部題目也都會整合至 LinDaiDai/niubility-coding-js 的issues
中,歡迎你們提供更好的解題思路,謝謝你們😁。node
一塊兒來看看本週的七道題吧。git
(題目來源:https://github.com/CavsZhouyou/Front-End-Interview-Notebook)github
咋了小夥伴們,感受這道題目很簡單是嗎?哈哈,數一數逗號的間隙好像就能得出答案了,好比這樣:web
可是這道題的答案並非4
喲,而是3
。json
console.log([,,,].length) // 3
複製代碼
因此最終咱們是須要把它想象成這樣的:數組
也就是最後一個逗號的後面是不算一項的。瀏覽器
這裏其實涉及到了一個名爲:尾後逗號
的概念,或者說是叫作終止逗號
。上面👆這道題好像看不出它有什麼做用,讓我來看看實際上爲何會有這個用法。
好比如今你的項目中這麼一個文件:
config.js:
const types = [
{ name: '帥' }, { name: '陽光' }, ] export { types }; 複製代碼
你們能夠看到,我在陽光
這一項的的後面是多加了一個","
的,此時我將這個代碼提交到git
上並標記爲版本1
。
若是這時候types
中又要添加一項名爲"可愛"
的配置項,我只須要在它下面再加上就好了,不須要去改動到原來代碼,此時你提交的代碼的diff
是長這樣的:
const types = [
{ name: '帥' }, { name: '陽光' }, + { + name: '可愛' + }, ] export { types }; 複製代碼
你們能夠看到,只有簡單的三行增量代碼,若是你沒有使用尾後逗號
的話,你提交的代碼的diff
會是這樣:
const types = [
{ name: '帥' }, { name: '陽光' - } + }, + { + name: '可愛' + } ] export { types }; 複製代碼
所以咱們能夠得出尾後逗號
它的做用:
「使得版本控制更加清晰,以及代碼維護麻煩更少。」
(固然,這種用法在.json
後綴的文件中是不能用的哈,由於JSON
它嚴格遵循它本身的語法要求)
因此迴歸到這道題中來,像這種使用了多於一個尾後逗號的數組,咱們就稱之爲稀疏數組
,稀疏數組它的長度是等於逗號的數量的。
所以:
console.log([,,,].length) // 3
複製代碼
這道題呆呆其實在不少地方都看到了,可是有的回答好像並不那麼靠譜。
回答這道題首先咱們須要知道一個概念:
瀏覽器環境:全局對象爲window
;而在node
環境下,是有一個名爲global
的對象,它的內部Class屬性
是爲"global"
。
內部Class屬性
也就是咱們經過Object.prototype.call(obj)
這種方式來獲取到的內容,好比:
console.log(Object.prototype.toString.call([1, 2, 3])); // "[object Array]"
複製代碼
(關於它的用法呆呆在《【精】從206個console.log()徹底弄懂數據類型轉換的前世此生(上)》中的toString
用法時說的也很詳細咯)
所以咱們能夠得出這種判斷方式:
var isBrowser = typeof window !== 'undefined'
&& ({}).toString.call(window) === '[object Window]'; var isNode = typeof global !== "undefined" && ({}).toString.call(global) == '[object global]'; 複製代碼
({}).toString.call()
和Object.prototype.toString.call()
用法一致,只不過在{}
的外面最好加上一個()
,也是爲了預防JS
將大括號{}
認爲是一個空的代碼塊(額,呆呆試了一下貌似也沒有這方面的問題)。
reduce
函數的第一個參數是一個回調函數,第二個參數爲可選的初始值。
若是有初始值的話,回調函數就會從數組的第0項開始執行,也就是會執行arr.length
次;
可是若是沒有初始值的話,會默認取數組的第0項爲初始值,回調函數會從數組的第1項開始執行,也就是會執行arr.length - 1
次。
這點從咱們手寫一個reduce
的實現就能夠看出來,代碼以下:
Array.prototype.MyReduce = function (fn, initialValue) {
var arr = Array.prototype.slice.call(this); var pre, startIndex; pre = initialValue ? initialValue : arr[0]; startIndex = initialValue ? 0 : 1; for (var i = startIndex; i < arr.length; i++) { pre = fn.call(null, pre, arr[i], i, this) } return pre } 複製代碼
過程分析:
map、reduce
這種方法都是數組原型對象上的方法,因此我將
MyReduce
定義在
Array.prototype
上,這樣你就能夠直接使用
ary.MyReduce()
這樣的方式調用它了(
ary是一個相似於這樣的數組[1, 2, 3]
)。
reduce
,它接收的第一個參數是一個回調函數,第二個是初始值
var arr = ...
的做用是獲取調用
MyReduce
函數的那個變量,也就是說
this
會指向那個變量,例如
ary.MyReduce()
,那麼此時
this
就爲
ary
。
var arr = this;
的方式而是使用
Array.prototype.slice.call(this)
,算是實現一個淺拷貝吧,由於
reduce
是不會改變原數組的。
reduce
中的回調函數的第一個參數
pre
,也就是上一次運行結果的返回值,能夠看到這裏就用到了初始值
initialValue
,若是存在初始值就取初始值,不存在則默認取數組第
0
項。(固然這裏直接用
initialValue ?
來判斷存不存在並不許確,由於咱們知道
0
也會被判斷爲
false
)
startIndex
,如果不存在初始值,則初始值是會取數組中的第
0
項的,至關於第
0
項並不須要運行,因此
startIndex
會是
1
,而若是有初始值的話則須要將數組的每一項都通過
fn
運行一下。
for
循環中使用
fn.call()
來調用
fn
函數,而且最後一個參數是要把原來的數組傳遞到回調函數中,也就是這裏的
this
。
label
標籤不會向用戶呈現任何特殊效果,它的做用是爲鼠標用戶改進了可用性。
也就是說當你使用了一個label
標籤和一個input
綁定起來以後,點擊label
標籤上的文字就會自動聚焦到input
上。
以下:
綁定的方式:
label
標籤上設置
for
屬性
input
標籤上設置和
for
屬性同樣的
id
例如:
<label for="username">username:</label>
<input type="text" name="username" id="username"/> 複製代碼
這裏有兩點須要注意的:
form
標籤內纔會生效
for
是和
id
對應的,並非和
name
你們在聽到自動完成這個詞,會有一點迷糊,自動完成什麼?
其實這個功能的做用是這樣的:
首先,autocomplete
是一個屬性,這個屬性能夠設置在form
標籤上,也能夠設置在其它的input
標籤上。
被設置了自動完成的標籤,會容許瀏覽器預測對字段的輸入。也就是說瀏覽器會根據你在這個輸入框中已經輸入過的值,留有一個"歷史記錄"
,方便咱們下次還想要輸入一樣的值。
例以下面這段代碼:
<form autocomplete="on">
testaccount: <input type="text" name="testaccount" /><br /> testpassword: <input type="text" name="testpassword" autocomplete="off" /><br /> <input type="submit" /> </form> 複製代碼
form
標籤的
autocomplete
打開,那麼這個表單下的全部元素都開啓了
autocomplete
testpassword
這一項的
autocomplete
關閉。
此時testaccout
是有自動完成功能的,而testpassword
沒有。那麼當咱們第一次在這兩個輸入框中輸入了內容並提交後。再次點擊testaccout
輸入框,就會出現咱們上一次輸入並提交的那個值,而點擊testpassword
時卻沒有。
效果以下:
因此咱們來作下總結吧😊:
autocomplete
屬性規定輸入字段是否應該啓用自動完成功能;
"on"
,另外一個值是
"off"
關閉;
autocomplete
屬性適用於
<form>
,以及下面的
<input>
類型:
text, search, url, telephone, email, password, datepickers, range , color
。
visibility
會有這麼幾個個屬性值:
visible
hidden
collapse
inherit
比較經常使用的多是前面兩個,用於控制元素的顯示隱藏。且咱們知道,設置爲hidden
是會隱藏元素,可是其餘元素的佈局不改變,至關於此元素變成透明。
inherit
則是從父元素繼承visibility
屬性的值。
而對於collapse
,可能用的不是特別多,咱們先來看下它的介紹:
hidden
是同樣的;
table
相關的元素,例如
table行,table group,table列,table column group
,它的表現卻跟
display: none
同樣,也就是說,它們佔用的空間也會釋放。
下面一塊兒來看看這個案例😊:
html代碼:
<table>
<tr class="tr1"> <td> tr1 </td> <td> tr1 </td> </tr> <tr> <td> tr2 </td> <td> tr2 </td> </tr> </table> 複製代碼
css代碼:
table {
border: 1px solid red; } td { border: 1px solid blue; } .tr1 { } 複製代碼
我在沒給.tr1
設置任何屬性的時候,頁面呈現的效果是這樣的,很正常:
若是設置了visibility: hidden
:
.tr1 {
visibility: hidden; } 複製代碼
效果以下:
雖然第一行被隱藏了,可是它的空間仍是在的,就像是"隱身"
了同樣。
而若是設置了visibility: collapse
:
.tr1 {
visibility: collapse; } 複製代碼
效果以下:
最終的效果會和display: none;
同樣。
若是你問呆呆這屬性有什麼實際的用處沒有...咳咳,抱歉,好像還真沒有😅。也多是呆呆不知道,知道的小夥伴還請提出喲,一塊兒學習一哈。
這兩個屬性值相信你們都不陌生了,先讓咱們來看個案例理解一下:
html代碼:
<div class="super">
<div class="sub1"> 我是呆呆的第一個崽 </div> <div class="sub2"> 我是呆呆的第二個崽 </div> <div class="sub3"> 我是呆呆的第三個崽 </div> </div> 複製代碼
css代碼:
.super {
width: 200px; height: 100px; background: skyblue; } .sub1 { background: #d0e4a9; } .sub2 { width: 100%; background: #c077af; } .sub3 { width: auto; background: #f8d29d; } 複製代碼
最開始時,三個崽表現的效果是同樣的,並沒有很大差異:
此時若是咱們對後面兩個崽作一下改動:
.sub2 {
width: 100%; padding-left: 10px; margin-left: 10px; background: #c077af; } .sub3 { width: auto; padding-left: 10px; margin-left: 10px; background: #f8d29d; } 複製代碼
給他們都加上左內邊距和左外邊距,此時的效果就變成了這樣:
你們會發現,設置了width: 100%
的崽,它的寬度會和父級的同樣,此時若是再給他設置了額外的padding
,那它就會比父級還要寬了,也就是會超出父級容器。而由於還設置了margin-left
,因此左邊也會有一段距離。
可是設置了width: auto
的崽就比較乖了,不管怎樣它都不會超出父級,而是選擇壓縮本身的寬度。
所以咱們能夠得出結論:
box-sizing: content-box;
的狀況):
width: auto;
它的總寬度是等於父寬度的(這裏的父寬度是指父級內容的寬度不包括
padding、border、margin
),即便給元素設置了
padding、border、margin
等屬性,它也會自動分配水平空間。
width: 100%;
它表示的是元素內容的寬度等於父寬度,因此它的總寬度是有可能超過父級的,由於若是設置了額外的
padding、border
,就可能比父級寬了。
width:100%
仍是
auto
,其計算的參照都是父級內容區
width
值,而非總寬度值,也就是不包括
padding、border、margin
。
width:auto
使用的多一些,由於這樣靈活;而
width:100%
使用比較少,由於在增長
padding
或者
margin
的時候,容易使其突破父級框,破壞佈局。
知識無價,支持原創。
參考文章:
你盼世界,我盼望你無bug
。這篇文章就介紹到這裏。
您每週也許會花48
小時的時間在工做💻上,會花49
小時的時間在睡覺😴上,也許還能夠再花20
分鐘的時間在呆呆的7道題上,日積月累,我相信咱們都能見證彼此的成長😊。
什麼?你問我爲何系列的名字叫DD
?由於呆呆
呀,哈哈😄。
喜歡「霖呆呆」的小夥還但願能夠關注霖呆呆的公衆號 LinDaiDai
或者掃一掃下面的二維碼👇👇👇。
我會不定時的更新一些前端方面的知識內容以及本身的原創文章🎉
你的鼓勵就是我持續創做的主要動力 😊。
往期題目能夠戳下面👇:
或者你也能夠查看github上的issues
:「我是issues」
本文使用 mdnice 排版