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

語言: CN / TW / HK

系列介紹

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

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

系列的形式主要是:3道JavaScript + 2道HTML + 2道CSS,幫助我們大家一起鞏固前端基礎。

所有題目也都會整合至 LinDaiDai/niubility-coding-jsissues中,歡迎大家提供更好的解題思路,謝謝大家😁。

一起來看看本週的七道題吧。

正題

一、使用delete刪除陣列元素,其長度會改變嗎?

(題目來源:github.com/haizlin/fe-…)

咱來寫個案例🌰看看就知道了:

var arr = [1, 2, 3]
delete arr[1]
console.log(arr)
console.log(arr.length)
複製程式碼

結果如下:

通過結果,我們可以得出結論:使用delete刪除陣列元素,其長度是不會改變的。

關於這一點,大家可以把陣列理解為是一個特殊的物件,其中的每一項轉換為物件的虛擬碼為:

key: value
// 對應:
0: 1
1: 2
2: 3
length: 3
複製程式碼

所以我們使用delete操作符刪除一個數組元素時,相當於移除了陣列中的一個屬性,被刪除的元素已經不再屬於該陣列。但是這種改變並不會影響陣列的length屬性。

擴充套件:

  • 如果你想讓一個數組元素繼續存在但是其值是 undefined,那麼可以使用將 undefined 賦值給這個元素而不是使用 delete。例如:arr[1] = undefined
  • 如果你想通過改變陣列的內容來移除一個數組元素,請使用splice() 方法。例如:arr.splice(1, 1)

github.com/LinDaiDai/n…

二、建立一個函式batches返回能烹飪出面包的最大值

(題目來源:github.com/30-seconds/…)

/**
batches函式接收兩個引數:
1. recipe 製作一個麵包需要的各個材料的值
2. available 現有的各個材料的值
要求傳入 recipe 和 available,然後根據兩者計算出能夠烹飪出面包的最大值
**/

// 0個麵包,因為 butter黃油需要50ml,但是現在只有48ml
batches(
  { milk: 100, butter: 50, flour: 5 },
  { milk: 132, butter: 48, flour: 51 }
)
batches(
  { milk: 100, butter: 4, flour: 10 },
  { milk: 1288, butter: 9, flour: 95 }
)

// 1個麵包
batches(
  { milk: 100, butter: 50, flour: 10 },
  { milk: 198, butter: 52, flour: 10 }
)

// 2個麵包
batches(
  { milk: 2, butter: 40, flour: 20 },
  { milk: 5, butter: 120, flour: 500 }
)
複製程式碼

這道題的解題思路其實就是比較recipeavailable兩個物件的每一個屬性值,用後者的屬性值除以前者的屬性值,然後得到一個數,例如0個麵包中的:

  • available.milk / recipe.milk,得到1.32
  • available.butter / recipe.butter,得到0.96
  • available.flour / recipe.flour,得到10.2

然後取三個結果中的最小值0.96,再向下取整,得出最終能製作的麵包個數為0

所以我們可以得出第一種解題方法:

const batches = (recipe, available) =>
  Math.floor(
    Math.min(...Object.keys(recipe).map(k => available[k] / recipe[k] || 0))
  )
複製程式碼

過程分析:

  • Object.keys(recipe),迭代recipe物件,得到所有的key['milk', 'butter', 'flour']
  • 之後使用map遍歷剛剛所有的key,並返回available[k]/recipe[k]的值:[1.32, 0.96, 10.2]
  • 需要得出上面一步陣列中的最小值,所以可以使用Math.min(...arr)方法來獲取
  • 最後將最小值0.96向下取整得到0

當然這道題你也可以使用Object.entries(),效果是一樣的:

const batches = (recipe, available) =>
  Math.floor(
    // Math.min(...Object.keys(recipe).map(k => available[k] / recipe[k] || 0))
    Math.min(...Object.entries(recipe).map(([k, v]) => available[k] / v || 0))
  )
複製程式碼

github.com/LinDaiDai/n…

三、typeof typeof 0 的結果?

(題目來源:github.com/30-seconds/…)

這道題其實不難,最終結果是"string"

過程分析:

  • typeof 0的結果為"number",是個字串
  • 所以typeof "number"的結果是"string"

github.com/LinDaiDai/n…

四、target="_blank"有哪些問題?

存在問題:

  1. 安全隱患:新開啟的視窗可以通過window.opener獲取到來源頁面的window物件即使跨域也可以。某些屬性的訪問被攔截,是因為跨域安全策略的限制。 但是,比如修改window.opener.location的值,指向另外一個地址,這樣新視窗有可能會把原來的網頁地址改了並進行頁面偽裝來欺騙使用者。
  2. 新開啟的視窗與原頁面視窗共用一個程序,若是新頁面有效能不好的程式碼也會影響原頁面

解決方案:

  1. 儘量不用target="_blank"

  2. 如果一定要用,需要加上rel="noopener"或者rel="noreferrer"。這樣新視窗的window.openner就是null了,而且會讓新視窗執行在獨立的程序裡,不會拖累原來頁面的程序。(不過,有些瀏覽器對效能做了優化,即使不加這個屬性,新視窗也會在獨立程序開啟。不過為了安全考慮,還是加上吧。)

(參考來源:慎用target="_blank"

github.com/LinDaiDai/n…

五、children以及childNodes的區別

  • children和只獲取該節點下的所有element節點
  • childNodes不僅僅獲取element節點還會獲取元素標籤中的空白節點
  • firstElementChild只獲取該節點下的第一個element節點
  • firstChild會獲取空白節點

github.com/LinDaiDai/n…

六、float:left對比position:absolute

相同點:

  • 脫離文件流,也就是將元素從普通的佈局排版中拿走,其他盒子在定位的時候,會當做脫離文件流的元素不存在而進行定位。
  • 包裹性:也就是都會讓元素inline-block化。等同於沒有高度與寬度的inline-block元素。
    • 對於塊狀元素預設的寬度為100%,若設定為了絕對定位則寬度由內容決定
    • 對於內聯元素原本設定width屬性無效,若設定了浮動則可以設定width
  • 破壞性:都會導致父級高度塌陷。但若是設定了絕對定位的話,其父級即使設定為float:left;也還是不能解決高度塌陷的問題。

不同點:

  • 雖然它們都會脫離文件流,但是使用float脫離文件流時,其他盒子會無視這個元素,但其他盒子內的文字依然會為這個元素讓出位置,環繞在周圍。而對於使用position:absolute脫離文件流的元素,其他盒子與其他盒子內的文字都會無視它。

github.com/LinDaiDai/n…

七、float:left對比inline-block

  • 文件流:浮動會脫離文件流,且使得被覆蓋的元素的文字內容會環繞在周圍;而inline-block不會脫離文件流也就不會覆蓋其它元素。浮動也會引發父級高度塌陷問題。
  • 水平位置:不能給有浮動元素的父級設定text-align:center使得子集浮動元素居中,而inline-block卻可以。
  • 垂直對齊inline-block元素沿著預設的基線對齊(baseline),若是兩個元素的font-size不同則可能會看到一高一低,你可以通過設定vertical-align: top或者bottom;來使得它們基於頂線或者底線對齊(注意這個是設定到元素本身而不是設定到它們的父級)。而浮動元素緊貼頂部,不會有這個問題。
  • 空白inline-block包含html空白節點。如果你的html中一系列元素每個元素之間都換行了,當你對這些元素設定inline-block時,這些元素之間就會出現空白。而浮動元素會忽略空白節點,互相緊貼。

針對第三點,垂直對齊可以看下面👇這個案例:

預設情況下:

css程式碼為:

.sub {
  background: hotpink;
  display: inline-block;
}
複製程式碼

設定了vertial-align: top;後:

css程式碼為:

.sub {
  background: hotpink;
  display: inline-block;
  vertical-align: top;
}
複製程式碼

github.com/LinDaiDai/n…

後語

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

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

什麼?你問我為什麼系列的名字叫DD?因為呆呆呀,哈哈😄。

喜歡霖呆呆的小夥還希望可以關注霖呆呆的公眾號 LinDaiDai 或者掃一掃下面的二維碼👇👇👇。

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

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

本文使用 mdnice 排版