溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript開發(fā)技巧

發(fā)布時間:2020-06-22 10:35:21 來源:億速云 閱讀:151 作者:Leah 欄目:web開發(fā)

這篇文章將為大家詳細講解有關JavaScript開發(fā)技巧,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲

數組

先來看使用數組中常用的一些小技巧。

數組去重

ES6提供了幾種簡潔的數組去重的方法,但該方法并不適合處理非基本類型的數組。對于基本類型的數組去重,可以使用... new Set()來過濾掉數組中重復的值,創(chuàng)建一個只有唯一值的新數組。

const array = [1, 1, 2, 3, 5, 5, 1]
const uniqueArray = [...new Set(array)];
console.log(uniqueArray);

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

這是ES6中的新特性,在ES6之前,要實現同樣的效果,我們需要使用更多的代碼。該技巧適用于包含基本類型的數組: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()方法返回的索引與當索索引進行比較,以確定當前項是否重復。

確保數組的長度

在處理網格結構時,如果原始數據每行的長度不相等,就需要重新創(chuàng)建該數據。為了確保每行的數據長度相等,可以使用Array.fill來處理:

let array = Array(5).fill('');
console.log(array);

> Result: (5) ["", "", "", "", ""]

數組映射

不使用Array.map來映射數組值的方法。

const array = [
    {
        name: '大漠',
        email: 'w3cplus@hotmail.com'
    },
    {
        name: 'Airen',
        email: 'airen@gmail.com'
    }
]
const name = Array.from(array, ({ name }) => name)

> Result: (2) ["大漠", "Airen"]

數組截斷

如果你想從數組末尾刪除值(刪除數組中的最后一項),有比使用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', '大漠', 'w3cplus.com', undefined, true, false, null, 'undefined', 'null', NaN, 'NaN', '1' + 0]
array.map(item => {
    return item
}).filter(Boolean)

> Result: (10) [1, "0", "1", "大漠", "w3cplus.com", 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)獲取數組的最后一項,除此之外還可以使用下面的方式來獲取數組的最后一項:

console.log(array.slice(array.length - 1))
> Result: [7]

過濾并排序字符串列表

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

在我們的例子里準備用不同版本語言的JavaScript 保留字的列表,但是你能發(fā)現,有很多重復的關鍵字而且它們并沒有按字母表順序排列。所以這是一個完美的字符串列表(數組)來測試我們的JavaScript小知識。

var 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, '大漠'], 3, ['blog', '1', 2, 3]]
const flatArray = [].concat(...arr)
console.log(flatArray)

> Result: (8) [1, 2, "大漠", 3, "blog", "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]

從數組中獲取最大值和最小值

可以使用Math.max和Math.min取出數組中的最大小值和最小值:

const numbers = [15, 80, -9, 90, -99]
const maxInNumbers = Math.max.apply(Math, numbers)
const minInNumbers = Math.min.apply(Math, numbers)

console.log(maxInNumbers)
> Result: 90

console.log(minInNumbers)
> Result: -99

另外還可以使用ES6的...運算符來完成:

const numbers = [1, 2, 3, 4];
Math.max(...numbers) 
> Result: 4

Math.min(...numbers) 
> > Result: 1

對象

在操作對象時也有一些小技巧。

使用...運算符合并對象或數組中的對象

同樣使用ES的...運算符可以替代人工操作,合并對象或者合并數組中的對象。

// 合并對象
const obj1 = {
    name: '大漠',
    url: 'w3cplus.com'
}
const obj2 = {
    name: 'airen',
    age: 30
}
const mergingObj = {...obj1, ...obj2}
> Result: {name: "airen", url: "w3cplus.com", age: 30}

// 合并數組中的對象
const array = [
    {
        name: '大漠',
        email: 'w3cplus@gmail.com'
    },
    {
        name: 'Airen',
        email: 'airen@gmail.com'
    }
]
const result = array.reduce((accumulator, item) => {
    return {
        ...accumulator,
        [item.name]: item.email
    }
}, {})
> Result: {大漠: "w3cplus@gmail.com", Airen: "airen@gmail.com"}

有條件的添加對象屬性

不再需要根據一個條件創(chuàng)建兩個不同的對象,以使它具有特定的屬性。為此,使用...操作符是最簡單的。

const getUser = (emailIncluded) => {
    return {
        name: '大漠',
        blog: 'w3cplus',
        ...emailIncluded && {email: 'w3cplus@hotmail.com'}
    }
}

const user = getUser(true)
console.log(user)
> Result: {name: "大漠", blog: "w3cplus", email: "w3cplus@hotmail.com"}

const userWithoutEmail = getUser(false)
console.log(userWithoutEmail)
> Result: {name: "大漠", blog: "w3cplus"}

解構原始數據

你可以在使用數據的時候,把所有數據都放在一個對象中。同時想在這個數據對象中獲取自己想要的數據。在這里可以使用ES6的Destructuring特性來實現。比如你想把下面這個obj中的數據分成兩個部分:

const obj = {
    name: '大漠',
    blog: 'w3cplus',
    email: 'w3cplus@hotmail.com',
    joined: '2019-06-19',
    followers: 45
}
let user = {}, userDetails = {}

({name: user.name, email: user.email, ...userDetails} = obj)
> {name: "大漠", blog: "w3cplus", email: "w3cplus@hotmail.com", joined: "2019-06-19", followers: 45}

console.log(user)
> Result: {name: "大漠", email: "w3cplus@hotmail.com"}

console.log(userDetails)
> Result: {blog: "w3cplus", joined: "2019-06-19", followers: 45}

動態(tài)更改對象的key

在過去,我們首先必須聲明一個對象,然后在需要動態(tài)屬性名的情況下分配一個屬性。在以前,這是不可能以聲明的方式實現的。不過在ES6中,我們可以實現:

const dynamicKey = 'email'
let obj = {
    name: '大漠',
    blog: 'w3cplus',
    [dynamicKey]: 'w3cplus@hotmail.com'
}

console.log(obj)
> Result: {name: "大漠", blog: "w3cplus", email: "w3cplus@hotmail.com"}

判斷對象的數據類型

使用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

上面的代碼相當于:

function isType(type){
    return function (target) {
        return `[object ${type}]` === Object.prototype.toString.call(target)
    }
}

isType('Array')([1,2,3])
> 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: '大漠'
};
if (obj.name) { 
    console.log(true) // > Result: true
}

這是可以的,但是你需要知道有兩種原生方法可以解決此類問題。in 操作符 和 Object.hasOwnProperty,任何繼承自Object的對象都可以使用這兩種方法。

var obj = {
    name: '大漠'
};
obj.hasOwnProperty('name');     // > true
'name' in obj;             // > true

obj.hasOwnProperty('valueOf');  // > false, valueOf 繼承自原型鏈
'valueOf' in obj;          // > true

兩者檢查屬性的深度不同,換言之hasOwnProperty只在本身有此屬性時返回true,而in操作符不區(qū)分屬性來自于本身或繼承自原型鏈。

這是另一個例子:

var myFunc = function() {
    this.name = '大漠';
};
myFunc.prototype.age = '10 days';
var user = new myFunc();

user.hasOwnProperty('name'); 
> Result: true

user.hasOwnProperty('age'); 
> Result: false,   //  因為age來自于原型鏈

創(chuàng)造一個純對象

使用Object.create(null)可以創(chuàng)建一個純對象,它不會從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中數據類型有NumberString、Boolean、ObjectArrayFunction等,在實際使用時會碰到數據類型的轉換。在轉換數據類型時也有一些小技巧。

轉換為布爾值

布爾值除了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

在某些上下文中,+會被解釋為連接操作符,而不是加法運算符。當這種情況發(fā)生時,希望返回一個整數,而不是浮點數,那么可以使用兩個波浪號~~。雙波浪號~~被稱為按位不運算符,它和-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

使用!!操作符轉換布爾值

有時候我們需要對一個變量查檢其是否存在或者檢查值是否有一個有效值,如果存在就返回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開發(fā)技巧就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI