Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537
于初學(xué)者,JavaScript 有哪些不為人知卻非常有用的技巧呢?在本文中,我們將一同為大家解密與分享。
作者 | Duomly
譯者 | 彎月,責(zé)編 | 屠敏
出品 | CSDN(ID:CSDNnews)
以下為譯文:
數(shù)組是Javascript中最常見的概念,我們有很多辦法來處理數(shù)組中的數(shù)據(jù)。考慮到數(shù)組是Javascript中最基本的概念之一,是初學(xué)者剛剛接觸編程時就學(xué)習(xí)的概念,我想通過本文介紹一些不為人知卻非常有用的技巧。我們開始吧!
從數(shù)組中刪除重復(fù)
在有關(guān)Javascript數(shù)組的面試問題中,有一個問題很常見:怎樣從Javascript數(shù)組中提取不重復(fù)的值。我有一個快捷簡便的方法:只需使用new Set即可。實(shí)現(xiàn)的方法有兩種:一種使用.from,另一種使用擴(kuò)展運(yùn)算符(...):
var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”];
很容易,是不是?
替換數(shù)組中指定的值
在編程時,有時候需要替換某個特定的值,有個非常簡單的方法來實(shí)現(xiàn)這一點(diǎn)。只需使用.split(start, 要刪除的值,要添加的值),然后設(shè)置好三個參數(shù),指明希望從哪里修改、要修改幾個值,以及新的值是什么。
var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”];
fruits.splice(0, 2, “potato”, “tomato”);
console.log(fruits); // returns [“potato”, “tomato”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”]
不使用.map實(shí)現(xiàn)映射
大概所有人都知道數(shù)組的.map方法,但還有另一個方法,可以用同樣簡潔的方式實(shí)現(xiàn)類似的效果。這種方法就是.from:
var friends = [
{ name: ‘John’, age: 22 },
{ name: ‘Peter’, age: 23 },
{ name: ‘Mark’, age: 24 },
{ name: ‘Maria’, age: 22 },
{ name: ‘Monica’, age: 21 },
{ name: ‘Martha’, age: 19 },
]
var friendsNames = Array.from(friends, ({name}) => name);
console.log(friendsNames); // returns [“John”, “Peter”, “Mark”, “Maria”, “Monica”, “Martha”]
清空數(shù)組
如果想把一個數(shù)組清空,但不想一個個刪除其中的元素,該怎么辦?其實(shí)只需一行代碼即可:將length設(shè)置為0。
var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”];
fruits.length = 0;
console.log(fruits); // returns
將數(shù)組轉(zhuǎn)化為對象
如果有一個數(shù)組,我們希望將其數(shù)據(jù)放到一個對象中,那么最快的方式就是使用擴(kuò)展運(yùn)算符(...):
var fruits = [“banana”, “apple”, “orange”, “watermelon”];
var fruitsObj = { …fruits };
console.log(fruitsObj); // returns {0: “banana”, 1: “apple”, 2: “orange”, 3: “watermelon”, 4: “apple”, 5: “orange”, 6: “grape”, 7: “apple”}
用數(shù)據(jù)填充數(shù)組
有時候需要創(chuàng)建一個數(shù)組并用數(shù)據(jù)填充,或者需要一個所有值都相同的數(shù)組,此時可以使用.fill方法簡潔明快地實(shí)現(xiàn):
var newArray = new Array(10).fill(“1”);
console.log(newArray); // returns [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”]
合并數(shù)組
你知道怎樣可以不使用.concat來合并數(shù)組嗎?最簡單的方法只需要一行代碼。你也許猜到了,那就是擴(kuò)展運(yùn)算符(...),它非常適合處理數(shù)組:
var fruits = [“apple”, “banana”, “orange”];
var meat = [“poultry”, “beef”, “fish”];
var vegetables = [“potato”, “tomato”, “cucumber”];
var food = […fruits, …meat, …vegetables];
console.log(food); // [“apple”, “banana”, “orange”, “poultry”, “beef”, “fish”, “potato”, “tomato”, “cucumber”]
求兩個數(shù)組的交集
這也是Javascript面試中最常遇到的問題,因?yàn)樗苷故境瞿闶欠駮褂脭?shù)組方法,以及邏輯如何。要找出兩個數(shù)組的交集,只需要使用之前使用的技巧,首先保證數(shù)組中的值不重復(fù),然后利用.filter和.includes方法即可。這樣就能找出同時出現(xiàn)在兩個數(shù)組中的元素。代碼如下:
var numOne = [0, 2, 4, 6, 8, 8];
var numTwo = [1, 2, 3, 4, 5, 6];
var duplicatedValues = […new Set(numOne)].filter(item => numTwo.includes(item));
console.log(duplicatedValues); // returns [2, 4, 6]
從數(shù)組中刪除假值
首先我們來定義假值。在Javascript中,假值包括false、0、''、、NaN、undefined。現(xiàn)在可以考慮怎樣從數(shù)組中刪除假值了。只需使用.filter方法即可實(shí)現(xiàn):
var mixedArr = [0, “blue”, “”, NaN, 9, true, undefined, “white”, false];
var trueArr = mixedArr.filter(Boolean);
console.log(trueArr); // returns [“blue”, 9, true, “white”]
從數(shù)組中獲取隨機(jī)值
有時候需要從數(shù)組中隨機(jī)選擇一個值。簡單、快捷、簡短且干凈的方式就是在數(shù)組長度的范圍內(nèi)生成一個隨機(jī)的索引。代碼如下:
var colors = [“blue”, “white”, “green”, “navy”, “pink”, “purple”, “orange”, “yellow”, “black”, “brown”];
var randomColor = colors[(Math.floor(Math.random() * (colors.length)))]
反轉(zhuǎn)數(shù)組
需要反轉(zhuǎn)數(shù)組時,我們不需要使用復(fù)雜的循環(huán)和函數(shù)來重新創(chuàng)建數(shù)組,因?yàn)橛幸粋€簡單的數(shù)組方法可以為我們做這件事,只需一行代碼,就能反轉(zhuǎn)數(shù)組。代碼如下:
var colors = [“blue”, “white”, “green”, “navy”, “pink”, “purple”, “orange”, “yellow”, “black”, “brown”];
var reversedColors = colors.reverse;
console.log(reversedColors); // returns [“brown”, “black”, “yellow”, “orange”, “purple”, “pink”, “navy”, “green”, “white”, “blue”]
.lastIndexOf方法
Javascript中有一個有趣的方法,可以讓我們找出指定元素最后出現(xiàn)的位置。例如,如果數(shù)組中有重復(fù)元素,那么可以找出該元素最后出現(xiàn)的位置。代碼如下:
var nums = [1, 5, 2, 6, 3, 5, 2, 3, 6, 5, 2, 7];
var lastIndex = nums.lastIndexOf(5);
console.log(lastIndex); // returns 9
對數(shù)組中的所有值求和
另一個Javascript工程師面試中常見的問題就是對數(shù)組中的所有元素求和。這個完全不需要害怕,只需使用.reduce方法,一行代碼就可以實(shí)現(xiàn)。代碼如下:
var nums = [1, 5, 2, 6];
var sum = nums.reduce((x, y) => x + y);
console.log(sum); // returns 14
總結(jié)
本文向你展示了13個編程技巧,可以保持代碼簡短整潔。同時別忘了,Javascript中還有許多不同的技巧值得探索,不僅是有關(guān)數(shù)組的技巧,也包括許多其他的數(shù)據(jù)類型。希望你喜歡本文的技巧,并能利用這些技巧改善開發(fā)流程。
原文:https://dev.to/duomly/13-useful-javascript-array-tips-and-tricks-you-should-know-2jfo
本文為 CSDN 翻譯,轉(zhuǎn)載請注明來源出處。
【END】
文共1933字,預(yù)計學(xué)習(xí)時長10分鐘
圖源:unsplash
眾所周知,JavaScript更新?lián)Q代的速度特別快,總能給人新鮮感,也一直有能讓我們挖掘探索的東西,新版ES2020就有許多特別厲害的功能讓人迫不及待想試試。
寫代碼的方法有很多,總有一些方法寫出來的代碼要更加簡潔清楚,這就需要一些小技巧了。本文就列出了一些對JavaScript開發(fā)人員有用的技巧,希望會對你有所幫助。
方法參數(shù)校驗(yàn)
JavaScript可以設(shè)置參數(shù)的默認(rèn)值,這提供了一個驗(yàn)證方法參數(shù)的小竅門:
const isRequired = () => { thrownew Error('param is required'); };
const print = (num =isRequired()) => { console.log(`printing ${num}`) };
print(2);//printing 2
print()// error
print(null)//printing null
格式化JSON編碼
你肯定對JSON.stringify 已經(jīng)很熟悉了,但你會用 stringify 將輸出格式化嗎?這個操作實(shí)際非常簡單。stringify 需要三個參數(shù),value , replacer 和space,后兩個是可選參數(shù),所以之前沒有用到過它,如果要縮進(jìn)JSON就必須設(shè)置space參數(shù)。
console.log(JSON.stringify({name:"John",Age:23},null,'\t'));>>>
{
"name": "John",
"Age": 23
}
https://bit.dev/eden/stringify-components/display-results
從數(shù)組中獲取唯一值
從數(shù)組中獲取唯一值要使用filter過濾出重復(fù)值,但有了新的set原生對象就變得順手多了。
let uniqueArray = [...newSet([1, 2, 3, 3,3,"school","school",'ball',false,false,true,true])];
>>> [1, 2, 3,"school", "ball", false, true]
篩選數(shù)字?jǐn)?shù)組
JavaScript數(shù)組帶有內(nèi)置的篩選方法。默認(rèn)情況下,該方法將數(shù)組元素轉(zhuǎn)換為字符串,并對其進(jìn)行字典排序。在對數(shù)字?jǐn)?shù)組進(jìn)行排序時可能會出現(xiàn)問題,這兒有一個簡單的解決方案:
[0,10,4,9,123,54,1].sort((a,b)=> a-b);>>> [0, 1, 4, 9, 10, 54, 123]
這個函數(shù)通過比較數(shù)字?jǐn)?shù)組中的兩個元素實(shí)現(xiàn)篩選,可以得到正確的輸出。
刪除數(shù)組中的虛假值
有時我們可能需要刪掉數(shù)組中的虛假值,即那些在JavaScript中等同于FALSE的值,JavaScript有六種虛假值,包括:
· undefined
· null
· NaN
· 0
· “” (空字符串)
· false
過濾出虛假值最簡單的方法是使用下面的函數(shù):
myArray
.filter(Boolean);
如果要對數(shù)組進(jìn)行一些修改,然后過濾新數(shù)組,可以嘗試如下操作。記住,原始myArray保持不變。
myArray
.map(item => {
// Do your changes and return thenew item
})
.filter(Boolean);
合并多個對象
圖源:unsplash
碰到要合并兩類或多類的情況時,下面的方法非常好用:
const user = {
name: 'John Ludwig',
gender: 'Male'
};const college = {
primary: 'Mani Primary School',
secondary: 'Lass Secondary School'
};const skills = {
programming: 'Extreme',
swimming: 'Average',
sleeping: 'Pro'
};const summary = {...user, ...college,...skills};
等所有promise完成后再行動
有時你需要等一些promise對象完成后才能進(jìn)行下一步操作,我們可以使用Promise.all 來同步完成。注意,所有Promise可以在單核CPU中同時運(yùn)行,在多核CPU中并行運(yùn)行。它的主要任務(wù)是等待傳遞給它的所有promise對象全部得到解析。
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Datarelease"),
Promise.reject(new Error('Somethingwent wrong'))];Promise.all(PromiseArray)
.then(data => console.log('allresolved! here are the resolve values:', data))
.catch(err => console.log('gotrejected! reason:', err))
Promise.all必須注意的要點(diǎn)是,如果其中一個promise被拒,就會發(fā)出錯誤警告。這意味著你的代碼不用等所有promise對象全部解析完畢。
如果不管promise是否被拒都想讓它全部運(yùn)行完,可以用Promise.allSettled,在ES2020的最終版本中使用這個方法:
const PromiseArray = [
Promise.resolve(100),
Promise.reject(null),
Promise.resolve("Datarelease"),
Promise.reject(new Error('Somethingwent wrong'))];Promise.allSettled(PromiseArray).then(res =>{
console.log(res);
}).catch(err => console.log(err));//[
//{status: "fulfilled", value: 100},
//{status: "rejected", reason: null},
//{status: "fulfilled", value: "Data release"},
//{status: "rejected", reason: Error: Something went wrong ...}
//]
盡管有些promise被拒,Promise.allSettled 會返回所有promise的結(jié)果。
禁用右鍵
盡管不多見,但有時你可能需要阻止用戶在網(wǎng)頁上使用鼠標(biāo)右鍵,這個簡單的代碼就能做到:
<body oncontextmenu="returnfalse">
<div></div>
</body>
利用別名節(jié)點(diǎn)解構(gòu)
解構(gòu)賦值是JavaScript的一種表達(dá)式,可以將數(shù)組中的值或?qū)ο髮傩越鈮簽椴煌淖兞浚也槐貓猿质褂矛F(xiàn)有的對象變量,而可以按照個人喜好對其重新命名:
const object = { number: 10 };//Grabbing number
const { number } = object;// Grabbing number and renaming it as otherNumber
const { number: otherNumber } = object;console.log(otherNumber); //10
獲取數(shù)組中的最后幾項
如果要提取數(shù)組最后幾項,可以使用slice方法,參數(shù)設(shè)置為負(fù)參數(shù):
let array = [0, 1, 2, 3, 4, 5,6, 7]
console.log(array.slice(-1));
>>>[7]
console.log(array.slice(-2));
>>>[6, 7]
console.log(array.slice(-3));
>>>[5, 6, 7]
這些可能會被忽視的小技巧可能會給你幫大忙,趕快學(xué)起來吧!
留言點(diǎn)贊關(guān)注
我們一起分享AI學(xué)習(xí)與發(fā)展的干貨
如轉(zhuǎn)載,請后臺留言,遵守轉(zhuǎn)載規(guī)范
本文已經(jīng)過原作者 Tapas Adhikary 授權(quán)翻譯
上傳文件功能可以說是項目經(jīng)常出現(xiàn)的需求。從在社交媒體上上傳照片到在求職網(wǎng)站上發(fā)布簡歷,文件上傳無處不在。在本文中,我們將討論 HTML文件上傳支持的10種用法,希望對你有用。
我們可以將input 類型指定為file,以在Web應(yīng)用程序中使用文件上傳功能。
<input type="file" id="file-uploader">
input filte 提供按鈕上傳一個或多個文件。默認(rèn)情況下,它使用操作系統(tǒng)的本機(jī)文件瀏覽器上傳單個文件。成功上傳后,F(xiàn)ile API 使得可以使用簡單的 JS 代碼讀取File對象。要讀取File對象,我們需要監(jiān)聽 change事件。
首先,通過id獲取文件上傳的實(shí)例:
const fileUploader = document.getElementById('file-uploader');
然后添加一個change 事件偵聽器,以在上傳完成后讀取文件對象, 我們從event.target.files屬性獲取上傳的文件信息:
fileUploader.addEventListener('change', (event) => {
const files = event.target.files;
console.log('files', files);
});
在控制臺中觀察輸出結(jié)果,這里關(guān)注一下FileList數(shù)組和File對象,該對象具有有關(guān)上傳文件的所有元數(shù)據(jù)信息。
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/rNLOyRm
如果我們想上傳多個文件,需要在標(biāo)簽上添加 multiple 屬性:
<input type="file" id="file-uploader" multiple />
現(xiàn)在,我們可以上傳多個文件了,以前面事例為基礎(chǔ),選擇多個文件上傳后,觀察一下控制臺的變化:
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/MWeamYp
每當(dāng)我們上傳文件時,File對象都有元數(shù)據(jù)信息,例如file name,size,last update time,type 等等。這些信息對于進(jìn)一步的驗(yàn)證和特殊處理很有用。
const fileUploader = document.getElementById('file-uploader');
// 聽更 change 件并讀取元數(shù)據(jù)
fileUploader.addEventListener('change', (event) => {
// 獲取文件列表數(shù)組
const files = event.target.files;
// 遍歷并獲取元數(shù)據(jù)
for (const file of files) {
const name = file.name;
const type = file.type ? file.type: 'NA';
const size = file.size;
const lastModified = file.lastModified;
console.log({ file, name, type, size, lastModified });
}
});
下面是單個文件上傳的輸出結(jié)果:
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/gOMaRJv
我們可以使用accept屬性來限制要上載的文件的類型,如果只想上傳的文件格式是 .jpg,.png 時,可以這么做:
<input type="file" id="file-uploader" accept=".jpg, .png" multiple>
在上面的代碼中,只能選擇后綴是.jpg和.png的文件。
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/OJXymRP
成功上傳文件后顯示文件內(nèi)容,站在用戶的角度上,如果上傳之后,沒有一個預(yù)覽的,就很奇怪也不體貼。
我們可以使用FileReader對象將文件轉(zhuǎn)換為二進(jìn)制字符串。然后添加load 事件偵聽器,以在成功上傳文件時獲取二進(jìn)制字符串。
// FileReader 實(shí)例
const reader = new FileReader();
fileUploader.addEventListener('change', (event) => {
const files = event.target.files;
const file = files[0];
reader.readAsDataURL(file);
reader.addEventListener('load', (event) => {
const img = document.createElement('img');
imageGrid.appendChild(img);
img.src = event.target.result;
img.alt = file.name;
});
});
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/zYBvdjZ
如果用戶上傳圖片過大,為了不讓服務(wù)器有壓力,我們需要限制圖片的大小,下面是允許用戶上傳小于 1M 的圖片,如果大于 1M 將上傳失敗。
fileUploader.addEventListener('change', (event) => {
// Read the file size
const file = event.target.files[0];
const size = file.size;
let msg = '';
// 檢查文件大小是否大于1MB
if (size > 1024 * 1024) {
msg = `<span style="color:red;">The allowed file size is 1MB. The file you are trying to upload is of ${returnFileSize(size)}</span>`;
} else {
msg = `<span style="color:green;"> A ${returnFileSize(size)} file has been uploaded successfully. </span>`;
}
feedback.innerHTML = msg;
});
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/pobjMKv
更好的用戶體驗(yàn)是讓用戶知道文件上傳進(jìn)度,前面我們用過了FileReader以及讀取和加載文件的事件。
const reader = new FileReader();
FileReader還有一個progress 事件,表示當(dāng)前上傳進(jìn)度,配合HTML5的progress標(biāo)簽,我們來模擬一下文件的上傳進(jìn)度。
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
// 計算完成百分比
const percent = (event.loaded / event.total) * 100;
// 將值綁定到 `progress`標(biāo)簽
progress.value = percent;
}
});
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/eYzpwYj
我們可以上傳整個目錄嗎?嗯,這是可能的,但有一些限制。有一個叫做webkitdirectory的非標(biāo)準(zhǔn)屬性(目前只有谷歌瀏覽器還有Microsoft Edge支持按照文件夾進(jìn)行上傳),它允許我們上傳整個目錄。
目前只有谷歌瀏覽器還有Microsoft Edge支持按照文件夾進(jìn)行上傳,具體可以看下百度云盤的網(wǎng)頁版的上傳按鈕,在火狐下就支持按照文件進(jìn)行上傳,而在谷歌和Edge下,就會給用戶提供一個下拉,讓用戶選擇是根據(jù)文件進(jìn)行上傳還是根據(jù)文件夾進(jìn)行上傳。
<input type="file" id="file-uploader" webkitdirectory />
用戶必須需要確認(rèn)才能上傳目錄
用戶單擊“上傳”按鈕后,就會進(jìn)行上傳。這里要注意的重要一點(diǎn)。FileList數(shù)組將以平面結(jié)構(gòu)的形式包含有關(guān)上載目錄中所有文件的信息。對于每個File對象,webkitRelativePath屬性表示目錄路徑。
例如,上傳一個主目錄及其下的其他文件夾和文件:
現(xiàn)在,F(xiàn)ile 對象將將webkitRelativePath填充為:
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/dyXYRKp
不支持文件上傳的拖拽就有點(diǎn) low 了,不是嗎?我們來看看如何通過幾個簡單的步驟實(shí)現(xiàn)這一點(diǎn)。
首先,創(chuàng)建一個拖放區(qū)域和一個可選的區(qū)域來顯示上傳的文件內(nèi)容。
<div id="container">
<h1>Drag & Drop an Image</h1>
<div id="drop-zone">
DROP HERE
</div>
<div id="content">
Your image to appear here..
</div>
</div>
通過它們各自的ID獲取dropzone和content 區(qū)域。
const dropZone = document.getElementById('drop-zone');
const content = document.getElementById('content');
添加一個dragover 事件處理程序,以顯示將要復(fù)制的內(nèi)容的效果:
dropZone.addEventListener('dragover', event => {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
});
接下來,我們需要一個drop事件監(jiān)聽器來處理。
dropZone.addEventListener('drop', event => {
// Get the files
const files = event.dataTransfer.files;
});
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/ExyVoXN
有一個特殊的方法叫做URL.createobjecturl(),用于從文件中創(chuàng)建唯一的URL。還可以使用URL.revokeObjectURL()方法來釋放它。
URL.revokeObjectURL() 靜態(tài)方法用來釋放一個之前已經(jīng)存在的、通過調(diào)用 URL.createObjectURL() 創(chuàng)建的 URL 對象。當(dāng)你結(jié)束使用某個 URL 對象之后,應(yīng)該通過調(diào)用這個方法來讓瀏覽器知道不用在內(nèi)存中繼續(xù)保留對這個文件的引用了。
fileUploader.addEventListener('change', (event) => {
const files = event.target.files;
const file = files[0];
const img = document.createElement('img');
imageGrid.appendChild(img);
img.src = URL.createObjectURL(file);
img.alt = file.name;
});
如果大家看到這里,有點(diǎn)激動,想手賤一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/BazzaoN
無論何時,如果你還想學(xué)習(xí)本文涉及的一些知識,你可以在這里嘗試。
https://html-file-upload.netlify.app/
*請認(rèn)真填寫需求信息,我們會在24小時內(nèi)與您取得聯(lián)系。