DD每週前端七題詳解-第六期

DD每週前端七題詳解-第六期

系列介紹

你盼世界,我盼望你無bug。Hello 你們好!我是霖呆呆!css

呆呆每週都會分享七道前端題給你們,系列名稱就是「DD每週七題」。html

系列的形式主要是:3道JavaScript + 2道HTML + 2道CSS,幫助咱們你們一塊兒鞏固前端基礎。前端

全部題目也都會整合至 LinDaiDai/niubility-coding-jsissues中,歡迎你們提供更好的解題思路,謝謝你們😁。node

一塊兒來看看本週的七道題吧。git

正題

1、[,,,]的長度

(題目來源:https://github.com/CavsZhouyou/Front-End-Interview-Notebook)github

咋了小夥伴們,感受這道題目很簡單是嗎?哈哈,數一數逗號的間隙好像就能得出答案了,好比這樣:web

可是這道題的答案並非4喲,而是3json

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
複製代碼

github.com/LinDaiDai/n…

2、如何判斷當前腳本運行在瀏覽器仍是 node 環境中?

這道題呆呆其實在不少地方都看到了,可是有的回答好像並不那麼靠譜。

回答這道題首先咱們須要知道一個概念:

瀏覽器環境:全局對象爲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將大括號{}認爲是一個空的代碼塊(額,呆呆試了一下貌似也沒有這方面的問題)。

github.com/LinDaiDai/n…

3、reduce方法有初始值和沒有初始值的區別?

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

github.com/LinDaiDai/n…

4、form表單中的label標籤的做用?

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

github.com/LinDaiDai/n…

5、HTML5中的自動完成功能autocomplete是作什麼的?

你們在聽到自動完成這個詞,會有一點迷糊,自動完成什麼?

其實這個功能的做用是這樣的:

首先,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

github.com/LinDaiDai/n…

6、CSS中的visibility有個collapse屬性值是幹嗎用的?

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;同樣。

若是你問呆呆這屬性有什麼實際的用處沒有...咳咳,抱歉,好像還真沒有😅。也多是呆呆不知道,知道的小夥伴還請提出喲,一塊兒學習一哈。

github.com/LinDaiDai/n…

7、塊狀元素width:100%與width:auto的區別?

這兩個屬性值相信你們都不陌生了,先讓咱們來看個案例理解一下:

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的時候,容易使其突破父級框,破壞佈局。

github.com/LinDaiDai/n…

參考文章

知識無價,支持原創。

參考文章:

後語

你盼世界,我盼望你無bug。這篇文章就介紹到這裏。

您每週也許會花48小時的時間在工做💻上,會花49小時的時間在睡覺😴上,也許還能夠再花20分鐘的時間在呆呆的7道題上,日積月累,我相信咱們都能見證彼此的成長😊。

什麼?你問我爲何系列的名字叫DD?由於呆呆呀,哈哈😄。

喜歡霖呆呆的小夥還但願能夠關注霖呆呆的公衆號 LinDaiDai 或者掃一掃下面的二維碼👇👇👇。

img
img

我會不定時的更新一些前端方面的知識內容以及本身的原創文章🎉

你的鼓勵就是我持續創做的主要動力 😊。

往期題目能夠戳下面👇:

或者你也能夠查看github上的issues「我是issues」

本文使用 mdnice 排版

相關文章
相關標籤/搜索