你盼世界,我盼望你無bug
。Hello 你們好!我是霖呆呆!前端
從這周起呆呆每週都會分享七道前端題給你們,系列名稱就是「DD每週七題」。git
系列的形式主要是:3道JavaScript
+ 2道HTML
+ 2道CSS
,幫助咱們你們一塊兒鞏固前端基礎。github
全部題目也都會整合至 LinDaiDai/niubility-coding-js 的issues
中,歡迎你們提供更好的解題思路,謝謝你們😁。web
console.log(Array(3))
console.log(Array(3, 4)) console.log(new Array(3)) console.log(new Array(3, 4)) console.log(Array.of(3)) console.log(Array.of(3, 4)) 複製代碼
「考察知識點:」數組
Array()
和
new Array()
Array()
參數個數不一樣時的不一樣表現
Array.of()
的做用
「結果:」瀏覽器
console.log(Array(3)) // [empty x 3]
console.log(Array(3, 4)) // [3, 4] console.log(new Array(3)) // [empty x 3] console.log(new Array(3, 4)) // [3, 4] console.log(Array.of(3)) // [3] console.log(Array.of(3, 4)) // [3, 4] 複製代碼
「總結:」編輯器
Array
使不使用
new
效果都是同樣的
Array
方法,若是參數是一位的話,這個參數表示的是數組的長度,並建立此長度的空數組
Array
方法,若是參數是多位的話則每個參數都是數組的一項,會按順序返回數組
Array.of()
接收任意個參數,將按順序成爲返回數組中的元素,並返回這個新數組。
// cool點的寫法:
[...Array(100).keys()] // 其餘方法: Array(100).join(",").split(",").map((v, i) => i) Array(100).fill().map((v, i) => i) 複製代碼
後面兩種方法相信你們都能看到懂,也沒啥好說的了😄,讓咱們仔細看一下這個比較cool
的寫法:ui
使用Array(100)
建立一個內容全爲empty
的數組:[empty x 100]
this
使用keys()
方法從數組建立一個包含數組鍵的可迭代對象:
可迭代對象是否是讓你想到了generator
,沒錯的,這裏的keys()
是Array.prototype
上的方法,你們可能會把它和咱們以前用的比較多的Object.keys()
搞混。
說一下它的做用吧,它其實就像剛剛介紹的同樣,會建立一個可迭代對象,那麼小夥伴們應該知道,一個可迭代對象返回的數據會是這樣的:
{ value: 0, done: false }
複製代碼
value
爲此次的返回值,done
爲當前可迭代對象的邏輯塊是否執行完成。
因此你會看到如下這段代碼是會這樣執行的:
let it = Array(100).keys()
console.log(it.next) // {value: 0, done: false} console.log(it.next) // {value: 1, done: false} console.log(it.next) // {value: 2, done: false} console.log(it.next) // {value: 3, done: false} 複製代碼
至於[...arr]
這個就是ES6
的寫法了,轉化爲數組,固然你也能夠直接用Array.from()
。這兩種方式都支持將「可迭代對象」轉換爲數組。
這道題的意思是:提供一個createArr()
方法,用此方法建立的數組知足arr[-1] = arr[arr.length - 1]
:
function createArr (...elements) {
// ...代碼 return arr } var arr1 = createArr(1, 2, 3) console.log(arr1[-1]) // 3 console.log(arr1[-2]) // 2 複製代碼
「解題思路:」
其實對於這類題目,我首先想到的會是Object.defineProperty()
或者Proxy
。由於這裏涉及到了對數組值的獲取,顯然用Proxy
是比較合適的。什麼?你問我爲何不用Object.defineProperty()
?由於這個方法是針對於對象的某一個屬性的呀,對數組來講不合適。
因此對於這道題,咱們也許可使用Proxy
代理每次傳入進來的下標,也就是重寫一下數組的get
方法,在這個方法中咱們去處理這方面的邏輯,一塊兒來看看代碼吧😊:
function createArr (...elements) {
let handler = { get (target, key, receiver) { // 第三個參數傳不傳均可以 let index = Number(key) // 或者 let index = ~~key if (index < 0) { index = String(target.length + index) } return Reflect.get(target, index, receiver) } } let target = [...elements] // 建立一個新數組 return new Proxy(target, handler) } var arr1 = createArr(1, 2, 3) console.log(arr1[-1]) // 3 console.log(arr1[-2]) // 2 複製代碼
「注意點:」
get
接收到的第二個參數key
表示的是數組下標,它是字符串形式,因此須要轉爲Number
,固然方法有不少種了,使用Number()
也能夠,使用~~
雙非按位取反運算符也能夠。對比於Number()
的好處就是Number(undefined)
會轉換爲NaN
;可是使用~~
能保證一直是數字,~~undefined === 0
。(什麼?你還不知道區別?那你得看霖呆呆的這篇文章了:JS中按位取反運算符~及其它運算符)
接下來只須要判斷一下傳入進來的下標是否是小於0的,小於0的話加上數組的長度就能夠了
而後返回index
這一項使用的是Reflect.get(target, index)
。什麼?爲何不直接用target[index]
?固然這樣也能夠,對比target[index]
的區別就是Reflect.get(target, index)
若是傳入的target
不是一個Object
的話(數組也屬於對象),就會報一個類型錯誤TypeError
,而target[index]
返回的會是一個undefined
。好比這樣:
var obj = 5
console.log(obj['b']) // undefined console.log(Reflect.get(obj, 'b')) // Uncaught TypeError: Reflect.get called on non-object 複製代碼
「擴展點:」
呆呆這邊主要是想擴展一下get
的第三個參數receiver
(接受者),在MDN
上的解釋是:
若是target
對象中指定了getter
,receiver
則爲getter
調用時的this
值。
來看個例子理解一下😊。
案例一
例如咱們開始有這麼一個對象:
var obj = {
fn: function () { console.log('lindaidai') } } 複製代碼
如今使用Proxy
來賦值到obj1
中:
var obj = {
fn: function () { console.log('lindaidai') } } var obj1 = new Proxy(obj, { get (target, key, receiver) { console.log(receiver === obj1) // true console.log(receiver === target) // false return target[key] } }) obj1.fn() 複製代碼
能夠看到,receiver
表示的是obj1
這個新的代理對象,target
表示的是被代理的對象obj
。
因此,receiver
能夠表示「使用代理對象自己」。
案例二
另外一種狀況,receiver
也能夠表示是「從其繼承的對象」。
var proxy = new Proxy({}, {
get (target, key, receiver) { return receiver; } }) console.log(proxy.getReceiver === proxy) // true var inherits = Object.create(proxy) console.log(inherits.getReceiver === inherits) // true 複製代碼
這個案例中,我新建了一個空對象的代理對象proxy
,使用proxy.getReceiver
獲取它的receiver
,發現它就是代理對象自己。
而若是我將這個代理對象做爲一個原型對象,建立出一個新的對象inherits
,也就是實現了原型式繼承,那麼這時候receiver
的值就是這個被繼承的對象inherits
。
「總結」:
Proxy
代理,來改變每次獲取數組的值。
Proxy
的
get
中,第二個參數是字符串,即便傳入的是數組下標。
Number()
的好處就是
Number(undefined)
會轉換爲
NaN
;可是使用
~~
能保證一直是數字,
~~undefined === 0
。
target[index]
的區別就是
Reflect.get(target, index)
若是傳入的
target
不是一個
Object
的話(數組也屬於對象),就會報一個類型錯誤
TypeError
,而
target[index]
返回的會是一個
undefined
。
Proxy
的
get
中,第三個參數
receiver
一般爲使用代理對象自己或從其繼承的對象。
IE8
如下
addEventListener
可有冒泡,可有捕獲;
attachEvent
只有冒泡,沒有捕獲。
on
,後者帶
on
this
指向當前元素,後者指向
window
第三個參數涉及到冒泡和捕獲,是true
時爲捕獲,是false
則爲冒泡。
或者是一個對象{passive: true}
,針對的是Safari
瀏覽器,禁止/開啓使用滾動的時候要用到。
div {
width: 200px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; } 複製代碼
div {
width: 200px; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; } 複製代碼
該方法適用於WebKit瀏覽器及移動端。
「跨瀏覽器兼容方案:」
p {
position:relative; line-height:1.4em; /* 3 times the line-height to show 3 lines */ height:4.2em; overflow:hidden; } p::after { content:"..."; font-weight:bold; position:absolute; bottom:0; right:0; padding:0 20px 1px 45px; } 複製代碼
你盼世界,我盼望你無bug
。這篇文章就介紹到這裏。
您每週也許會花48
小時的時間在工做💻上,會花49
小時的時間在睡覺😴上,也許還能夠再花20
分鐘的時間在呆呆的7道題上,日積月累,我相信咱們都能見證彼此的成長😊。
什麼?你問我爲何系列的名字叫DD
?由於呆呆
呀,哈哈😄。
喜歡「霖呆呆」的小夥還但願能夠關注霖呆呆的公衆號 LinDaiDai
或者掃一掃下面的二維碼👇👇👇。
我會不定時的更新一些前端方面的知識內容以及本身的原創文章🎉
你的鼓勵就是我持續創做的主要動力 😊。
本文使用 mdnice 排版