您當前的位置:首頁 > 書法

使用Javascirpt的一些小技巧

作者:由 a958598028 發表于 書法時間:2021-03-06

陣列

先來羅列陣列操作中,常用的一些小技巧。

陣列去重

在ES6中,你首先想到的應該是使用

new Set()

來過濾掉陣列中重複的值。但該方法並不適合處理非基本型別的陣列。

const

array

=

1

1

2

3

5

5

1

const

uniqueArray

=

[。。。

newSet

array

)]

console

log

uniqueArray

>

Result

4

1

2

3

5

該技巧適用於包含基本型別的陣列:

undefined

null

boolean

string

number

。如果陣列中包含了一個

object

function

或其他陣列,那就需要使用其他方法。

除了上面的方法之外,還可以使用

Array。from(new Set())

來實現:

const array = [1, 1, 2, 3, 5, 5, 1]

Array。from(new Set(array))

> Result:(4) [1, 2, 3, 5]

另外,還可以使用

Array

。filter

indexOf()

來實現:

const array = [1, 1, 2, 3, 5, 5, 1]

array。filter((arr, index) => array。indexOf(arr) === index)

> Result:(4) [1, 2, 3, 5]

注意,

indexOf()

方法將返回陣列中第一個出現的陣列項。這就是為什麼我們可以在每次迭代中將

indexOf()

方法返回的索引與當索索引進行比較,以確定當前項是否重複。

確保陣列的長度

在處理網格結構時,如果原始資料每行的長度不相等,就需要重新建立該資料。為了確保每行的資料長度相等,可以使用

Array。fill

來處理:

let array = Array(5)。fill(‘’)

console。log(array);

> Result: (5) [“”, “”, “”, “”, “”]

陣列截斷

如果你想從陣列末尾刪除值(刪除陣列中的最後一項),有比使用

splice()

更快的替代方法。

例如,你知道原始陣列的大小,可以重新定義陣列的

length

屬性的值,就可以實現從陣列末尾刪除值:

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

console。log(array。length)

> Result: 10

array。length = 4

console。log(array)

> Result: (4) [0, 1, 2, 3]

這是一個特別簡潔的解決方案。但是,

slice()

方法執行更快,效能更好:

let array = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

array = array。slice(0, 4)

console。log(array)

> Result: [0, 1, 2, 3]

過濾掉陣列中的falsy值

如果你想過濾陣列中的

falsy

值,比如

0

undefined

null

false

,那麼可以透過

map

filter

方法實現:

const array = [0, 1, ‘0’, ‘1’, undefined, true, false, null, ‘undefined’, ‘null’, NaN, ‘NaN’, ‘1’ + 0]

array。map(item => {

return item

})。filter(Boolean)

> Result: (10) [1, “0”, “1”, true, “undefined”, “null”, “NaN”, “10”]

獲取陣列的最後一項

陣列的

slice()

取值為正值時,從陣列的開始處擷取陣列的項,如果取值為負整數時,可以從陣列末屬開始獲取陣列項。

let array = [1, 2, 3, 4, 5, 6, 7]

const firstArrayVal = array。slice(0, 1)

> Result: [1]

const lastArrayVal = array。slice(-1)

> Result: [7]

console。log(array。slice(1))

> Result: (6) [2, 3, 4, 5, 6, 7]

console。log(array。slice(array。length))

> Result: []

正如上面示例所示,使用

array。slice(-1)

獲取陣列的最後一項。

過濾並排序字串列表

你可能有一個很多名字組成的列表,需要過濾掉重複的名字並按字母表將其排序。

在例子裡準備用不同版本語言的JavaScript 保留字的列表,但是你能發現,有很多重複的關鍵字而且它們並沒有按字母表順序排列。所以這是一個完美的字串列表(陣列)來測試。

const

keywords

=

‘do’

‘if’

‘in’

‘for’

‘new’

‘try’

‘var’

‘case’

‘else’

‘enum’

‘null’

‘this’

‘true’

‘void’

‘with’

‘break’

‘catch’

‘class’

‘const’

‘false’

‘super’

‘throw’

‘while’

‘delete’

‘export’

‘import’

‘return’

‘switch’

‘typeof’

‘default’

‘extends’

‘finally’

‘continue’

‘debugger’

‘function’

‘do’

‘if’

‘in’

‘for’

‘int’

‘new’

‘try’

‘var’

‘byte’

‘case’

‘char’

‘else’

‘enum’

‘goto’

‘long’

‘null’

‘this’

‘true’

‘void’

‘with’

‘break’

‘catch’

‘class’

‘const’

‘false’

‘final’

‘float’

‘short’

‘super’

‘throw’

‘while’

‘delete’

‘double’

‘export’

‘import’

‘native’

‘public’

‘return’

‘static’

‘switch’

‘throws’

‘typeof’

‘boolean’

‘default’

‘extends’

‘finally’

‘package’

‘private’

‘abstract’

‘continue’

‘debugger’

‘function’

‘volatile’

‘interface’

‘protected’

‘transient’

‘implements’

‘instanceof’

‘synchronized’

‘do’

‘if’

‘in’

‘for’

‘let’

‘new’

‘try’

‘var’

‘case’

‘else’

‘enum’

‘eval’

‘null’

‘this’

‘true’

‘void’

‘with’

‘break’

‘catch’

‘class’

‘const’

‘false’

‘super’

‘throw’

‘while’

‘yield’

‘delete’

‘export’

‘import’

‘public’

‘return’

‘static’

‘switch’

‘typeof’

‘default’

‘extends’

‘finally’

‘package’

‘private’

‘continue’

‘debugger’

‘function’

‘arguments’

‘interface’

‘protected’

‘implements’

‘instanceof’

‘do’

‘if’

‘in’

‘for’

‘let’

‘new’

‘try’

‘var’

‘case’

‘else’

‘enum’

‘eval’

‘null’

‘this’

‘true’

‘void’

‘with’

‘await’

‘break’

‘catch’

‘class’

‘const’

‘false’

‘super’

‘throw’

‘while’

‘yield’

‘delete’

‘export’

‘import’

‘public’

‘return’

‘static’

‘switch’

‘typeof’

‘default’

‘extends’

‘finally’

‘package’

‘private’

‘continue’

‘debugger’

‘function’

‘arguments’

‘interface’

‘protected’

‘implements’

‘instanceof’

因為我們不想改變我們的原始列表,所以我們準備用高階函式叫做

filter

,它將基於我們傳遞的回撥方法返回一個新的過濾後的陣列。回撥方法將比較當前關鍵字在原始列表裡的索引和新列表中的索引,僅當索引匹配時將當前關鍵字push到新陣列。

最後我們準備使用

sort

方法排序過濾後的列表,sort只接受一個比較方法作為引數,並返回按字母表排序後的列表。

在ES6下使用箭頭函式看起來更簡單:

const filteredAndSortedKeywords = keywords

。filter((keyword, index) => keywords。lastIndexOf(keyword) === index)

。sort((a, b) => a < b ? -1 : 1)

這是最後過濾和排序後的JavaScript保留字列表:

console

log

filteredAndSortedKeywords

>

Result

‘abstract’

‘arguments’

‘await’

‘boolean’

‘break’

‘byte’

‘case’

‘catch’

‘char’

‘class’

‘const’

‘continue’

‘debugger’

‘default’

‘delete’

‘do’

‘double’

‘else’

‘enum’

‘eval’

‘export’

‘extends’

‘false’

‘final’

‘finally’

‘float’

‘for’

‘function’

‘goto’

‘if’

‘implements’

‘import’

‘in’

‘instanceof’

‘int’

‘interface’

‘let’

‘long’

‘native’

‘new’

‘null’

‘package’

‘private’

‘protected’

‘public’

‘return’

‘short’

‘static’

‘super’

‘switch’

‘synchronized’

‘this’

‘throw’

‘throws’

‘transient’

‘true’

‘try’

‘typeof’

‘var’

‘void’

‘volatile’

‘while’

‘with’

‘yield’

清空陣列

如果你定義了一個數組,然後你想清空它。 通常,你會這樣做:

let array = [1, 2, 3, 4];

function emptyArray() {

array = [];

}

emptyArray();

但是,這有一個效率更高的方法來清空陣列。 你可以這樣寫:

let array = [1, 2, 3, 4]

function emptyArray() {

array。length = 0

}

emptyArray()

拍平多維陣列

使用

。。。

運算子,將多維陣列拍平:

const

arr

=

1

2

‘a’

],

3

‘b’

‘1’

2

3

]]

const

flatArray

=

[]。

concat

(。。。

arr

console

log

flatArray

>

Result

8

1

2

“a”

3

“b”

“1”

2

3

不過上面的方法只適用於二維陣列。不過透過遞迴呼叫,可以使用它適用於二維以下的陣列:

function

flattenArray

arr

{

const

flattened

=

[]。

concat

(。。。

arr

);

return

flattened

some

item

=>

Array

isArray

item

))

flattenArray

flattened

flattened

}

const

array

=

1

2

‘大漠’

],

3

[[

‘blog’

‘1’

],

2

3

]]

const

flatArr

=

flattenArray

array

console

log

flatArr

>

Result

8

1

2

“大漠”

3

“blog”

“1”

2

3

也可以使用Generator 函式,使用yield*遞迴遍歷陣列,最後利用Generator 與 Iterator 介面的關係,生成拍平後新的函式。(Generator 函式就是遍歷器生成函式,因此可以把 Generator 賦值給物件的

Symbol。iterator

屬性,從而使得該物件具有 Iterator 介面。)

function

flatten

arr

{

function

*

gen

arr

{

if

Array

isArray

arr

))

{

for

const

item

of

arr

{

yield

*

gen

item

}

}

else

{

yield

arr

}

}

return

Array

from

gen

arr

))

}

let

arr

=

[[[

1

2

],

3

4

5

],

6

7

]],

8

console

log

flatten

arr

))

>

Result

8

1

2

3

4

5

6

7

8

Array。from

方法可以將兩類物件轉為真正的陣列:類似陣列的物件(array-like object)和可遍歷(iterable)的物件。因此直接傳入Generator,即可生成新的陣列。

Array。prototype。flat()

用於將巢狀的陣列“拉平”,變成一維的陣列。該方法返回一個新陣列,對原資料沒有影響。

1

2

3

4

]]。

flat

()

>

Result

4

1

2

3

4

上面程式碼中,原陣列的成員裡面有一個數組,

flat()

方法將子陣列的成員取出來,新增在原來的位置。

flat()

預設只會“拉平”一層,如果想要“拉平”多層的巢狀陣列,可以將

flat()

方法的引數寫成一個整數,表示想要拉平的層數,預設為1。

[1, 2, [3, [4, 5]]]。flat()

// [1, 2, 3, [4, 5]]

[1, 2, [3, [4, 5]]]。flat(2)

// [1, 2, 3, 4, 5]

上面程式碼中,

flat()

的引數為2,表示要“拉平”兩層的巢狀陣列。

如果不管有多少層巢狀,都要轉成一維陣列,可以用

Infinity

關鍵字作為引數。

[1, [2, [3]]]。flat(Infinity)

// [1, 2, 3]

從陣列中獲取最大值和最小值

可以使用

Math。max

Math。min

取出陣列中的最大小值和最小值:

const

numbers

=

1

2

3

4

Math

max

(。。。

numbers

>

Result

4

Math

min

(。。。

numbers

>

Result

1

物件

使用...拓展運算符合並物件或陣列中的物件

同樣使用ES6的

。。。

運算子可以替代人工操作,合併物件或者合併陣列中的物件。

// 合併物件

const

obj1

=

{

name

‘name1’

url

‘w3c。com’

}

const

obj2

=

{

name

‘name2’

age

30

}

const

mergingObj

=

{。。。

obj1

。。。

obj2

}

>

Result

{

name

“name2”

url

“w3c。com”

age

30

}

// 合併陣列中的物件

const

array

=

{

name

‘David’

email

‘david@w3c。com’

},

{

name

‘Airen’

email

‘airen@w3c。com’

}

const

result

=

array

reduce

((

accumulator

item

=>

{

return

{

。。。

accumulator

item

name

item

email

}

},

{})

>

Result

{

David

“david@w3c。com”

Airen

“airen@w3c。com”

}

需要注意的時,用

。。。

拓展運算合併後的結果,是對原始物件的淺複製。原始物件為引用物件時,修改原始物件或合併後的物件,都會同時修改兩邊的結果。

有條件的新增物件屬性

不再需要根據一個條件建立兩個不同的物件,以使它具有特定的屬性。為此,使用

。。。

運算子是最簡單的。

const getUser = (emailIncluded) => {

return {

name: ‘David’,

blog: ‘w3c’,

。。。emailIncluded && {email: ‘david@w3c。com’}

}

}

const user = getUser(true)

console。log(user)

> Result: {name: “David”, blog: “w3c”, email: “david@w3c。com”}

const userWithoutEmail = getUser(false)

console。log(userWithoutEmail)

> Result: {name: “David”, blog: “w3c”}

判斷物件的資料型別

使用

Object。prototype。toString

配合閉包來實現物件資料型別的判斷:

const isType = type => target => `[object ${type}]` === Object。prototype。toString。call(target)

const isArray = isType(‘Array’)([1, 2, 3])

console。log(isArray)

> Result: true

或者:

const isType = type => target => `[object ${type}]` === Object。prototype。toString。call(target)

const isString = isType(‘String’)

const res = isString((‘1’))

console。log(res)

> Result: true

檢查某物件是否有某屬性

當你需要檢查某屬性是否存在於一個物件,你可能會這樣做:

var obj = {

name: ‘David’

};

if (obj。name) {

console。log(true) // > Result: true

}

這是可以的,但是你需要知道有兩種原生方法可以解決此類問題。

in

運算子 和

Object。hasOwnProperty

,任何繼承自

Object

的物件都可以使用這兩種方法。

var obj = {

name: ‘David’

};

obj。hasOwnProperty(‘name’); // > true

‘name’ in obj; // > true

obj。hasOwnProperty(‘valueOf’); // > false, valueOf 繼承自原型鏈

‘valueOf’ in obj; // > true

兩者檢查屬性的深度不同,換言之

hasOwnProperty

只在本身有此屬性時返回

true

,而

in

運算子不區分屬性來自於本身或繼承自原型鏈。

這是另一個例子:

var

myFunc

=

function

()

{

this

name

=

‘David’

};

myFunc

prototype

age

=

‘10 days’

var

user

=

new

myFunc

();

user

hasOwnProperty

‘name’

);

>

Result

true

user

hasOwnProperty

‘age’

);

>

Result

false

因為age來自於原型鏈

補充:現在,你也可以使用Reflect。has()來檢查。

Reflect。has

方法對應

name in obj

裡面的

in

運算子。

var obj = {

name: ‘David’

};

// 舊寫法

‘name’ in obj // true

// 新寫法

Reflect。has(obj, ‘name’) // true

如果

Reflect。has()

方法的第一個引數不是物件,將會報錯。

創造一個純物件

使用

Object。create(null)

可以建立一個純物件,它不會從

Object

類繼承任何方法(例如:建構函式、

toString()

等):

const

pureObject

=

Object

create

null

);

console

log

pureObject

);

//=> {}

console

log

pureObject

constructor

);

//=> undefined

console

log

pureObject

toString

);

//=> undefined

console

log

pureObject

hasOwnProperty

);

//=> undefined

資料型別轉換

JavaScript中資料型別有

Number

String

Boolean

Object

Array

Function

等,在實際使用時會碰到資料型別的轉換。在轉換資料型別時也有一些小技巧。

轉換為布林值

布林值除了

true

false

之外,JavaScript還可以將所有其他值視為“

真實的

”或“

虛假的

”。除非另有定義,JavaScript中除了

0

‘’

null

undefined

NaN

false

之外的值都是

真實的

我們可以很容易地在真和假之間使用

運算子進行切換,它也會將型別轉換為

Boolean

。比如:

const isTrue = !0;

const isFasle = !1;

const isFasle = !!0 // !0 => true,true的反即是false

console。log(isTrue)

> Result: true

console。log(typeof isTrue)

> Result: ‘boolean’

這種型別的轉換在條件語句中非常方便,比如將

!1

當作

false

轉換為字串

我們可以使用運算子

+

後緊跟一組空的引號

‘’

快速地將數字或布林值轉為字串:

const val = 1 + ‘’

const val2 = false + ‘’

console。log(val)

> Result: “1”

console。log(typeof val)

> Result: “string”

console。log(val2)

> Result: “false”

console。log(typeof val2)

> Result: “string”

轉換為數值

上面我們看到了,使用

+

緊跟一個空的字串

‘’

就可以將數值轉換為字串。相反的,使用加法運算子

+

可以快速實現相反的效果。

let int = ‘12’

int = +int

console。log(int)

> Result: 12

console。log(typeof int)

> Result: ‘number’

用同樣的方法可以將布林值轉換為數值:

console。log(+true)

> Return: 1

console。log(+false)

> Return: 0

在某些上下文中,

+

會被解釋為

連線運算子

,而不是

加法

運算子。當這種情況發生時,希望返回一個整數,而不是浮點數,那麼可以使用兩個波浪號

~~

。雙波浪號

~~

被稱為

按位不運算子

,它和

-n - 1

等價。例如,

~15 = -16

。這是因為

- (-n - 1) - 1 = n + 1 - 1 = n

。換句話說,

~ - 16 = 15

我們也可以使用

~~

將數字字串轉換成整數型:

const int = ~~‘15’

console。log(int)

> Result: 15

console。log(typeof int)

> Result: ‘number’

同樣的,

NOT

運算子也可以用於布林值:

~true = -2

~false = -1

浮點數轉換為整數

平常都會使用

Math。floor()

Math。ceil()

Math。round()

將浮點數轉換為整數。在JavaScript中還有一種更快的方法,即使用

|

(位或運算子)將浮點數截斷為整數。

console

log

23。9

|

0

);

>

Result

23

console

log

-

23。9

|

0

);

>

Result

-

23

|

的行為取決於處理的是正數還是負數,所以最好只在確定的情況下使用這個快捷方式。

如果

n

是正數,則

n | 0

有效地向下舍入。如果

n

是負數,它有效地四捨五入。更準確的說,該操作刪除小數點後的內容,將浮點數截斷為整數。還可以使用

~~

來獲得相同的舍入效果,如上所述,實際上任何位運算子都會強制浮點數為整數。這些特殊操作之所以有效,是因為一旦強制為整數,值就保持不變。

|

還可以用於從整數的末尾刪除任意數量的數字。這意味著我們不需要像下面這樣來轉換型別:

let str = “1553”;

Number(str。substring(0, str。length - 1));

> Result: 155

我們可以像下面這樣使用

|

運算子來替代:

console

log

1553

/

10

|

0

>

Result:

155

console

log

1553

/

100

|

0

>

Result:

15

console

log

1553

/

1000

|

0

>

Result:

1

使用

Math。trunc

方法去除一個數的小數部分,返回整數部分。

Math。trunc(4。1) // 4

Math。trunc(4。9) // 4

Math。trunc(-4。1) // -4

Math。trunc(-4。9) // -4

Math。trunc(-0。1234) // -0

對於非數值,

Math。trunc

內部使用

Number

方法將其先轉為數值。

Math。trunc(‘123。456’) // 123

Math。trunc(true) //1

Math。trunc(false) // 0

Math。trunc(null) // 0

對於空值和無法擷取整數的值,返回

NaN

Math。trunc(NaN); // NaN

Math。trunc(‘foo’); // NaN

Math。trunc(); // NaN

Math。trunc(undefined) // NaN

使用!!運算子轉換布林值

有時候我們需要對一個變數查檢其是否存在或者檢查值是否有一個有效值,如果存在就返回

true

值。為了做這樣的驗證,我們可以使用

!!

運算子來實現是非常的方便與簡單。對於變數可以使用

!!variable

做檢測,只要變數的值為:

0

null

“ ”

undefined

或者

NaN

都將返回的是

false

,反之返回的是

true

。比如下面的示例:

function

Account

cash

{

this

cash

=

cash

this

hasMoney

=

!!

cash

}

var

account

=

new

Account

100。50

);

console

log

account

cash

);

>

Result

100。50

console

log

account

hasMoney

);

>

Result

true

var

emptyAccount

=

new

Account

0

);

console

log

emptyAccount

cash

);

>

Result

0

console

log

emptyAccount

hasMoney

);

>

Result

false

在這個示例中,只要

account。cash

的值大於

0

,那麼

account。hasMoney

返回的值就是

true

還可以使用

!!

運算子將

truthy

falsy

值轉換為布林值:

!!

“”

// > false

!!

0

// > false

!!

null

// > false

!!

undefined

// > false

!!

NaN

// > false

!!

“hello”

// > true

!!

1

// > true

!!

{}

// > true

!!

[]

// > true

原文參考:

使用JavaScript的一些小技巧_JavaScript, JavaScript技巧 教程_w3cplus

標簽: Result  log  陣列  array  true