于初学者,JavaScript 有哪些不为人知却非常有用的技巧呢?在本文中,我们将一同为大家解密与分享。
作者 | Duomly
译者 | 弯月,责编 | 屠敏
出品 | CSDN(ID:CSDNnews)
以下为译文:
数组是Javascript中最常见的概念,我们有很多办法来处理数组中的数据。考虑到数组是Javascript中最基本的概念之一,是初学者刚刚接触编程时就学习的概念,我想通过本文介绍一些不为人知却非常有用的技巧。我们开始吧!
从数组中删除重复
在有关Javascript数组的面试问题中,有一个问题很常见:怎样从Javascript数组中提取不重复的值。我有一个快捷简便的方法:只需使用new Set即可。实现的方法有两种:一种使用.from,另一种使用扩展运算符(...):
var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”];
很容易,是不是?
替换数组中指定的值
在编程时,有时候需要替换某个特定的值,有个非常简单的方法来实现这一点。只需使用.split(start, 要删除的值,要添加的值),然后设置好三个参数,指明希望从哪里修改、要修改几个值,以及新的值是什么。
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实现映射
大概所有人都知道数组的.map方法,但还有另一个方法,可以用同样简洁的方式实现类似的效果。这种方法就是.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”]
清空数组
如果想把一个数组清空,但不想一个个删除其中的元素,该怎么办?其实只需一行代码即可:将length设置为0。
var fruits = [“banana”, “apple”, “orange”, “watermelon”, “apple”, “orange”, “grape”, “apple”];
fruits.length = 0;
console.log(fruits); // returns
将数组转化为对象
如果有一个数组,我们希望将其数据放到一个对象中,那么最快的方式就是使用扩展运算符(...):
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”}
用数据填充数组
有时候需要创建一个数组并用数据填充,或者需要一个所有值都相同的数组,此时可以使用.fill方法简洁明快地实现:
var newArray = new Array(10).fill(“1”);
console.log(newArray); // returns [“1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”, “1”]
合并数组
你知道怎样可以不使用.concat来合并数组吗?最简单的方法只需要一行代码。你也许猜到了,那就是扩展运算符(...),它非常适合处理数组:
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”]
求两个数组的交集
这也是Javascript面试中最常遇到的问题,因为它能展示出你是否会使用数组方法,以及逻辑如何。要找出两个数组的交集,只需要使用之前使用的技巧,首先保证数组中的值不重复,然后利用.filter和.includes方法即可。这样就能找出同时出现在两个数组中的元素。代码如下:
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]
从数组中删除假值
首先我们来定义假值。在Javascript中,假值包括false、0、''、、NaN、undefined。现在可以考虑怎样从数组中删除假值了。只需使用.filter方法即可实现:
var mixedArr = [0, “blue”, “”, NaN, 9, true, undefined, “white”, false];
var trueArr = mixedArr.filter(Boolean);
console.log(trueArr); // returns [“blue”, 9, true, “white”]
从数组中获取随机值
有时候需要从数组中随机选择一个值。简单、快捷、简短且干净的方式就是在数组长度的范围内生成一个随机的索引。代码如下:
var colors = [“blue”, “white”, “green”, “navy”, “pink”, “purple”, “orange”, “yellow”, “black”, “brown”];
var randomColor = colors[(Math.floor(Math.random() * (colors.length)))]
反转数组
需要反转数组时,我们不需要使用复杂的循环和函数来重新创建数组,因为有一个简单的数组方法可以为我们做这件事,只需一行代码,就能反转数组。代码如下:
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中有一个有趣的方法,可以让我们找出指定元素最后出现的位置。例如,如果数组中有重复元素,那么可以找出该元素最后出现的位置。代码如下:
var nums = [1, 5, 2, 6, 3, 5, 2, 3, 6, 5, 2, 7];
var lastIndex = nums.lastIndexOf(5);
console.log(lastIndex); // returns 9
对数组中的所有值求和
另一个Javascript工程师面试中常见的问题就是对数组中的所有元素求和。这个完全不需要害怕,只需使用.reduce方法,一行代码就可以实现。代码如下:
var nums = [1, 5, 2, 6];
var sum = nums.reduce((x, y) => x + y);
console.log(sum); // returns 14
总结
本文向你展示了13个编程技巧,可以保持代码简短整洁。同时别忘了,Javascript中还有许多不同的技巧值得探索,不仅是有关数组的技巧,也包括许多其他的数据类型。希望你喜欢本文的技巧,并能利用这些技巧改善开发流程。
原文:https://dev.to/duomly/13-useful-javascript-array-tips-and-tricks-you-should-know-2jfo
本文为 CSDN 翻译,转载请注明来源出处。
【END】
文共1933字,预计学习时长10分钟
图源:unsplash
众所周知,JavaScript更新换代的速度特别快,总能给人新鲜感,也一直有能让我们挖掘探索的东西,新版ES2020就有许多特别厉害的功能让人迫不及待想试试。
写代码的方法有很多,总有一些方法写出来的代码要更加简洁清楚,这就需要一些小技巧了。本文就列出了一些对JavaScript开发人员有用的技巧,希望会对你有所帮助。
方法参数校验
JavaScript可以设置参数的默认值,这提供了一个验证方法参数的小窍门:
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 已经很熟悉了,但你会用 stringify 将输出格式化吗?这个操作实际非常简单。stringify 需要三个参数,value , replacer 和space,后两个是可选参数,所以之前没有用到过它,如果要缩进JSON就必须设置space参数。
console.log(JSON.stringify({name:"John",Age:23},null,'\t'));>>>
{
"name": "John",
"Age": 23
}
https://bit.dev/eden/stringify-components/display-results
从数组中获取唯一值
从数组中获取唯一值要使用filter过滤出重复值,但有了新的set原生对象就变得顺手多了。
let uniqueArray = [...newSet([1, 2, 3, 3,3,"school","school",'ball',false,false,true,true])];
>>> [1, 2, 3,"school", "ball", false, true]
筛选数字数组
JavaScript数组带有内置的筛选方法。默认情况下,该方法将数组元素转换为字符串,并对其进行字典排序。在对数字数组进行排序时可能会出现问题,这儿有一个简单的解决方案:
[0,10,4,9,123,54,1].sort((a,b)=> a-b);>>> [0, 1, 4, 9, 10, 54, 123]
这个函数通过比较数字数组中的两个元素实现筛选,可以得到正确的输出。
删除数组中的虚假值
有时我们可能需要删掉数组中的虚假值,即那些在JavaScript中等同于FALSE的值,JavaScript有六种虚假值,包括:
· undefined
· null
· NaN
· 0
· “” (空字符串)
· false
过滤出虚假值最简单的方法是使用下面的函数:
myArray
.filter(Boolean);
如果要对数组进行一些修改,然后过滤新数组,可以尝试如下操作。记住,原始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对象完成后才能进行下一步操作,我们可以使用Promise.all 来同步完成。注意,所有Promise可以在单核CPU中同时运行,在多核CPU中并行运行。它的主要任务是等待传递给它的所有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必须注意的要点是,如果其中一个promise被拒,就会发出错误警告。这意味着你的代码不用等所有promise对象全部解析完毕。
如果不管promise是否被拒都想让它全部运行完,可以用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的结果。
禁用右键
尽管不多见,但有时你可能需要阻止用户在网页上使用鼠标右键,这个简单的代码就能做到:
<body oncontextmenu="returnfalse">
<div></div>
</body>
利用别名节点解构
解构赋值是JavaScript的一种表达式,可以将数组中的值或对象属性解压为不同的变量,且不必坚持使用现有的对象变量,而可以按照个人喜好对其重新命名:
const object = { number: 10 };//Grabbing number
const { number } = object;// Grabbing number and renaming it as otherNumber
const { number: otherNumber } = object;console.log(otherNumber); //10
获取数组中的最后几项
如果要提取数组最后几项,可以使用slice方法,参数设置为负参数:
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]
这些可能会被忽视的小技巧可能会给你帮大忙,赶快学起来吧!
留言点赞关注
我们一起分享AI学习与发展的干货
如转载,请后台留言,遵守转载规范
本文已经过原作者 Tapas Adhikary 授权翻译
上传文件功能可以说是项目经常出现的需求。从在社交媒体上上传照片到在求职网站上发布简历,文件上传无处不在。在本文中,我们将讨论 HTML文件上传支持的10种用法,希望对你有用。
我们可以将input 类型指定为file,以在Web应用程序中使用文件上传功能。
<input type="file" id="file-uploader">
input filte 提供按钮上传一个或多个文件。默认情况下,它使用操作系统的本机文件浏览器上传单个文件。成功上传后,File API 使得可以使用简单的 JS 代码读取File对象。要读取File对象,我们需要监听 change事件。
首先,通过id获取文件上传的实例:
const fileUploader = document.getElementById('file-uploader');
然后添加一个change 事件侦听器,以在上传完成后读取文件对象, 我们从event.target.files属性获取上传的文件信息:
fileUploader.addEventListener('change', (event) => {
const files = event.target.files;
console.log('files', files);
});
在控制台中观察输出结果,这里关注一下FileList数组和File对象,该对象具有有关上传文件的所有元数据信息。
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/rNLOyRm
如果我们想上传多个文件,需要在标签上添加 multiple 属性:
<input type="file" id="file-uploader" multiple />
现在,我们可以上传多个文件了,以前面事例为基础,选择多个文件上传后,观察一下控制台的变化:
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/MWeamYp
每当我们上传文件时,File对象都有元数据信息,例如file name,size,last update time,type 等等。这些信息对于进一步的验证和特殊处理很有用。
const fileUploader = document.getElementById('file-uploader');
// 听更 change 件并读取元数据
fileUploader.addEventListener('change', (event) => {
// 获取文件列表数组
const files = event.target.files;
// 遍历并获取元数据
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 });
}
});
下面是单个文件上传的输出结果:
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/gOMaRJv
我们可以使用accept属性来限制要上载的文件的类型,如果只想上传的文件格式是 .jpg,.png 时,可以这么做:
<input type="file" id="file-uploader" accept=".jpg, .png" multiple>
在上面的代码中,只能选择后缀是.jpg和.png的文件。
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/OJXymRP
成功上传文件后显示文件内容,站在用户的角度上,如果上传之后,没有一个预览的,就很奇怪也不体贴。
我们可以使用FileReader对象将文件转换为二进制字符串。然后添加load 事件侦听器,以在成功上传文件时获取二进制字符串。
// FileReader 实例
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;
});
});
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/zYBvdjZ
如果用户上传图片过大,为了不让服务器有压力,我们需要限制图片的大小,下面是允许用户上传小于 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;
});
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/pobjMKv
更好的用户体验是让用户知道文件上传进度,前面我们用过了FileReader以及读取和加载文件的事件。
const reader = new FileReader();
FileReader还有一个progress 事件,表示当前上传进度,配合HTML5的progress标签,我们来模拟一下文件的上传进度。
reader.addEventListener('progress', (event) => {
if (event.loaded && event.total) {
// 计算完成百分比
const percent = (event.loaded / event.total) * 100;
// 将值绑定到 `progress`标签
progress.value = percent;
}
});
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/eYzpwYj
我们可以上传整个目录吗?嗯,这是可能的,但有一些限制。有一个叫做webkitdirectory的非标准属性(目前只有谷歌浏览器还有Microsoft Edge支持按照文件夹进行上传),它允许我们上传整个目录。
目前只有谷歌浏览器还有Microsoft Edge支持按照文件夹进行上传,具体可以看下百度云盘的网页版的上传按钮,在火狐下就支持按照文件进行上传,而在谷歌和Edge下,就会给用户提供一个下拉,让用户选择是根据文件进行上传还是根据文件夹进行上传。
<input type="file" id="file-uploader" webkitdirectory />
用户必须需要确认才能上传目录
用户单击“上传”按钮后,就会进行上传。这里要注意的重要一点。FileList数组将以平面结构的形式包含有关上载目录中所有文件的信息。对于每个File对象,webkitRelativePath属性表示目录路径。
例如,上传一个主目录及其下的其他文件夹和文件:
现在,File 对象将将webkitRelativePath填充为:
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/dyXYRKp
不支持文件上传的拖拽就有点 low 了,不是吗?我们来看看如何通过几个简单的步骤实现这一点。
首先,创建一个拖放区域和一个可选的区域来显示上传的文件内容。
<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 区域。
const dropZone = document.getElementById('drop-zone');
const content = document.getElementById('content');
添加一个dragover 事件处理程序,以显示将要复制的内容的效果:
dropZone.addEventListener('dragover', event => {
event.stopPropagation();
event.preventDefault();
event.dataTransfer.dropEffect = 'copy';
});
接下来,我们需要一个drop事件监听器来处理。
dropZone.addEventListener('drop', event => {
// Get the files
const files = event.dataTransfer.files;
});
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/ExyVoXN
有一个特殊的方法叫做URL.createobjecturl(),用于从文件中创建唯一的URL。还可以使用URL.revokeObjectURL()方法来释放它。
URL.revokeObjectURL() 静态方法用来释放一个之前已经存在的、通过调用 URL.createObjectURL() 创建的 URL 对象。当你结束使用某个 URL 对象之后,应该通过调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。
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;
});
如果大家看到这里,有点激动,想手贱一下,可以 CodePen 玩玩,地址:https://codepen.io/atapas/pen/BazzaoN
无论何时,如果你还想学习本文涉及的一些知识,你可以在这里尝试。
https://html-file-upload.netlify.app/
*请认真填写需求信息,我们会在24小时内与您取得联系。