整合营销服务商

电脑端+手机端+微信端=数据同步管理

免费咨询热线:

高级前端开发需要知道的 25 个 JavaScrip

高级前端开发需要知道的 25 个 JavaScript 单行代码

. 不使用临时变量来交换变量的值

例如我们想要将 a 于 b 的值交换

let a=1, b=2;


// 交换值
[a, b]=[b, a];


// 结果: a=2, b=1

这行代码使用数组解构赋值的方式来交换两个变量的值,无需定义新的临时变量。这个巧妙的技巧可让代码看起来更简洁明了。语法[a, b]=[b, a]通过解构右侧的数组并将其分配给左侧来实现交换它们的值。

2. 对象解构,让数据访问更便捷

const { name, age }={ name: '张三', age: 23 };


// 结果: name='张三', age=23

这里使用对象解构赋值的方式将对象中的属性直接提取到新的变量中。这种方法简化了访问对象属性的过程,并增强了代码的可读性。

3. 浅克隆对象


const originalObj={ name: '张三', age: 24 };


const clonedObj={ ...originalObj };


// 结果: clonedObj={ name: '张三', age: 24 }
// 此时改变 clonedObj 的属性,将不会影响到原始对象 originalObj


通过使用扩展运算符 ( ...) 创建originalObj的浅克隆对象。此技术将所有可枚举的自身属性从原始对象复制到新对象。

4. 合并对象

const obj1={ name: '张三' };
const obj2={ age: 22 };


const mergedObj={ ...obj1, ...obj2 };


// 结果: mergedObj={ name: '张三', age: 22 }

与克隆类似,通过扩展运算符将obj1和合并obj2为一个新的对象。如果有重叠的属性,则最后一个对象的属性将覆盖前一个对象的属性。

5. 清理数组

const arr=[ 0, 1, false, 2, '', 3 ];


const cleanedArray=arr.filter(Boolean);


// 结果: cleanedArray=[1, 2, 3]

通过Array.prototype.filter()函数并使用Boolean函数作为回调。它将会从数组中删除所有假值( 0,false,null,undefined,'',NaN)。

6. 将 NodeList 转换为数组

const nodesArray=[ ...document.querySelectorAll('div')];

通过扩展运算符将NodeList( document.querySelectorAll函数的返回值) 转换为 JavaScript 数组,从而能够使用数组的map方法filter去操作查找到的元素。

7. 检查数组是否满足指定条件

例如我们要判断一个数组中是否存在负数

const arr=[ 1, 2, 3, -5, 4 ];


// 数组中是否有负数
const hasNegativeNumbers=arr.some(num=> num < 0);


// 结果: hasNegativeNumbers=true

Array.prototype.some()函数用于检查数组中是否至少有一个元素,通过所提供的回调函数实现的测试(此处判断是否是负数,返回true表示通过)

另外,还可以使用Array.prototype.every()来检查数组的所有元素是否全部通过测试(此处判断是否是正数)

const arr=[ 1, 2, 3, -5, 4 ];


// 数组元素是否全部为正
const allPositive=arr.every(num=> num > 0);


// 结果: allPositive=false

8. 将文本复制到剪贴板

navigator.clipboard.writeText('Text to copy');

通过使用 Clipboard API 以编程方式将文本复制到剪贴板。这是一种最新的复制方法,可让文本复制变得无缝且高效(但目前各大浏览器支持度还不是很高,需要考虑兼容性问题)。

9. 删除数组重复项

const arr=[1, 2, 2, 3, 4, 4, 5];


const unique=[...new Set(arr)];


// 结果: unique=[1, 2, 3, 4, 5]

这里利用了Set对象存储的值会保持唯一,以及扩展运算符能将Set转换回数组的特性。这是一种优雅的删除数组中重复项的方式。

10. 取两个数组的交集

const arr1=[1, 2, 3, 4];
const arr2=[2, 4, 6, 8];


// 取两个数组中公共的元素
const intersection=arr1.filter(value=> arr2.includes(value));


// 结果: intersection=[2, 4]

此示例通过使用Array.prototype.filter()函数去查找arr1与arr2中的公共元素。传入的回调函数会检查arr2是否包含arr1的每一个元素,从而得到两个数组的交集。

可以在笔COOL上运行上述演示代码

笔COOL,一个功能完备前端作品分享平台、使用便捷的在线HTML/CSS/JS代码编辑器,浏览器输入 bi.cool 即可访

11. 求数组元素的总和

const arr=[1, 2, 3, 4];


// 求总和
const sum=arr.reduce((total, value)=> total + value, 0);


// 结果: sum=10

此示例使用Array.prototype.reduce()方法将数组中所有的值全部累加起来。reduce方法接收一个回调函数和一个初始值(即前一个回调函数累加值的初始值),这个回调函数有两个参数:累加值total和当前值value。它将会遍历数组所有元素,将每个元素添加到总和中(总和初始为0)。

12. 根据指定条件判断,是否给对象的属性赋值

const condition=true;
const value='你好,世界';


// 如果条件为真,则将 value 变量的值赋给 newObject.key 属性
const newObject={...(condition && {key: value})};


// 结果: newObject={ key: '你好,世界' }

此案例使用扩展运算符 (...) 与短路求值(&&),将属性有条件地添加到对象中。如果condition为真,则会将{key: value}扩展到对象中;否则不进行任何操作。

13. 使用变量作为对象的键

const dynamicKey='name';
const value='张三';


// 使用一个动态的变量作为 key
const obj={[dynamicKey]: value};


// 结果: obj={ name: '张三' }

这种语法称为计算属性名,它允许使用变量作为对象的键。方括号内的dynamicKey表达式会计算其值,以将其用作属性名称。

14. 离线状态检查器


const isOnline=navigator.onLine ? '在线' : '离线';


// 结果: isOnline='在线' 或 '离线'

这段代码使用三元运算符检查浏览器的在线状态(navigator.onLine),如果为真则返回'在线',否则返回'离线'。这是一种动态检查用户网络连接状态的方法。

15. 离开页面弹出确认对话框

window.onbeforeunload=()=> '你确定要离开吗?';
这行代码与window的onbeforeunload事件挂钩,当用户离开页面时会弹出一个确认对话框,一般用于防止用户因未保存更改就关闭页面而导致数据丢失。


16. 对象数组,根据对象的某个key求对应值的总和

const arrayOfObjects=[{x: 1}, {x: 2}, {x: 3}];


// 指定要求和的 key值
const sumBy=(arr, key)=> arr.reduce((acc, obj)=> acc + obj[key], 0);


// 传入 'x',求元素对象 key 为 'x' 的值的总和
sumBy(arrayOfObjects, 'x'));


// 结果: 6

sumBy函数使用Array.prototype.reduce()对数组中元素特定键的值求和。这是一种根据给定键计算对象数组总和的灵活方法。

17. 将 url 问号后面的查询字符串转为对象

const query='name=John&age=30';


// 将字符串解析为对象
const parseQuery=query=> Object.fromEntries(new URLSearchParams(query));


// 结果: parseQuery={ name: 'John', age: '30' }

此示例将一个查询字符串转换为了一个对象。其中URLSearchParams会进行字符串解析,它将返回一个可迭代对象,然后在通过Object.fromEntries将它转换为对象,从而使 URL 参数检索变得方便多了。

18. 将秒数转换为时间格式的字符串

const seconds=3661; // 一小时是 3600 秒,多出 61 秒


const toTimeString=seconds=> new Date(seconds * 1000).toISOString().substr(11, 8);


toTimeString(seconds));


// 结果: '01:01:01'

此示例将秒数转换为 HH:MM:SS 格式的字符串。它通过给定的秒数加上时间戳起始点来创建一个新的 Date 对象,然后将其转换为 ISO 字符串,并提取时间部分得到结果。

19. 求某对象所有属性值的最大值

// 数学、语文、英语成绩
const scores={ math: 95, chinese: 99, english: 88 };


const maxObjectValue=obj=> Math.max(...Object.values(obj));


// 最高分
maxObjectValue(scores));


// 结果: 99

此示例用于在对象所有的属性值中找到最大值。其中Object.values(obj)将对象所有的属性值提取为数组,然后使用展开运算符将数组的所有元素作为Math.max函数的参数进行最大值查找。

20. 判断对象的值中是否包含有某个值

const person={ name: '张三', age: 30 };


const hasValue=(obj, value)=> Object.values(obj).includes(value);


hasValue(person, 30);


// 结果: true

hasValue函数会检查对象的值中是否存在指定的值。其中Object.values(obj)用于获取对象中所有的值的数组,然后通过includes(value)检查指定值是否在该数组中。

21. 安全访问深度嵌套的对象属性

const user={ profile: { name: '张三' } };


const userName=user.profile?.name ?? '匿名';


// 结果: userName='张三'

此代码首先演示了如何使用可选链运算符 (?.) 安全地访问user.profile的name值。如果user.profile是undefined或null,它会短路并返回undefined,从而避免潜在的类型错误TypeError。

然后,使用空值合并运算符 (??) 检查左侧是否为null或undefined,如果是,则使用默认值'匿名'。这可确保后备值不会是其他假值(如''或0)。这对于访问数据结构中可能不存在某些中间属性的深层嵌套属性非常有用。

在 JavaScript 中,空值合并运算符 (??) 和逻辑或 (||) 都可以用于提供默认值,但它们处理假值的方式有所不同。

在上面的例子中,如果把??改为||,行为会稍微有些不同。||的左侧如果为假值,它将会返回右侧的值。JavaScript 中的假值包括null、undefined、0、NaN、''(空字符串)和false。这意味着||左边的值不仅仅是null或undefined,如果还是其他假值,那么都将返回右侧的值。

22. 条件执行语句

const isEligible=true;


isEligible && performAction();


// 如果 isEligible 为真,则调用 performAction()

利用逻辑 AND ( &&) 运算符,函数performAction()仅会在isEligible结果为true时执行。这是一种无需if语句即可有条件地执行函数的简介语法。这对于根据某些条件执行函数非常有用,尤其是在事件处理或回调中。

如果想要条件赋值,则可以这样写

const isEligible=true;
let value='';


// 需要将赋值语句用用括号括起来
isEligible && (value='条件达成');


// 如果 isEligible 为真,则执行 (value='条件达成') 语句

23. 创建包含值为指定数字范围的数组

例如创建数字5以内所有正数的数组

const range=Array.from({ length: 5 }, (_, i)=> i + 1);


// 结果: range=[1, 2, 3, 4, 5]

Array.from()从类数组或可迭代对象创建一个新数组。这里,它接受一个具有属性length和映射函数的对象。映射函数 ( (_, i)=> i + 1) 使用索引 ( i) 生成从 1 到 5 的数字。下划线 ( _) 是一种惯例,表示未使用该参数。

24. 提取文件扩展名

const fileName='example.png';


const getFileExtension=str=> str.slice(((str.lastIndexOf(".") - 1) >>> 0) + 2);


// 结果: getFileExtension='png'

这个案例实现了从字符串中提取文件扩展名。它先找到最后一次出现点号 (.) 位置,然后截取从该位置到末尾的字符串。位运算符 (>>>) 确保了即使未找到点号 (.) ,操作也是安全的,因为在这种情况下仍然会返回一个空字符串。

25. 切换元素的 class

const element=document.querySelector('.my-element');


const toggleClass=(el, className)=> el.classList.toggle(className);


toggleClass(element, 'active');

toggleClass函数使用classList.toggle()方法从一个元素的 class 列表中添加或移除某个 class。如果该 class 存在,则删除,否则添加。这是一种根据用户交互或应用程序状态动态更新 class 的方法。非常适合实现响应式设计元素,例如菜单根据用户操作显示或隐藏。

以上 25 个 JavaScript 单行代码,以简短高效的方式提供强大的功能。希望您今天能有所收获!

在笔COOL上运行上述演示代码

笔COOL,一个功能完备前端作品分享平台、使用便捷的在线HTML/CSS/JS代码编辑器,浏览器输入 bi.cool 即可访问

上一章,我们已经实现了从网页代码文件中提取文字,但是我们发现,提取的文字中有很多空白行,如下图

这样,篇幅可能很长很长。现在我们有一个需要,就是能不能将这些空白行去除掉?本章就来研究这个问题。

首先,我们先对程序进行一下优化处理,把上一张最后程序中的自定义函数“去除html代码”,移动到通用函数库中。

上一章最后的程序如下

移动后程序变成下面这个样子

此时,自定义函数已经移到了通用函数库中。于是,我们看到,优化后的程序更加简单易懂,下面我们研究去除空行的问题。

按照以前的习惯,我们先对主程序进行下改造,改造后的主程序变成下面的模样

上面红线标注的这一行,就是我们新增加的内容。我们编写了一个函数,名字叫做去除空行,详细内容如下图,下面我们研究一下这个函数

第四行,我们定义的这个函数以及传入的参数

第五行,定义了回收内容的变量

第六行,用换行符把内容分割成列表

第七行,对列表内所有的行进行遍历

第八行,对列表中的内容进行空格删除,然后看看是不是为空,用这样的方式判断行内是否有内容。

第九行,对有内容的行进行回收。

第十行,返回结果

于是我们得到了完整的程序,如下图

运行后的效果如下图

于是我们看到,所有的空行没有了。剩下的行都是有内容的行。

载说明:原创不易,未经授权,谢绝任何形式的转载

学习制作自定义指令:构建安全的URL清理指令

开篇

Vue.js配备了一套默认指令,对于常见的使用情况非常重要。这些默认指令包括v-for、v-html和v-text。此外,Vue.js还赋予我们注册定制指令以满足特定需求的能力。

自定义指令通常包括生命周期钩子,并且可以在“mounted”、“updated”和“beforeUnmount”等阶段进行操作。这些钩子接收应用指令的元素及其关联值,使它们能够对输入执行特定的操作。

此外,还可以根据特定的生命周期钩子(如'onUpdated'或'beforeUnmount')有选择地触发函数

注册指令

指令可以通过三种不同的方式进行注册。它们可以在脚本设置(setup 函数)内部或设置函数(setup函数)之外进行注册,也可以在应用程序初始化期间进行全局注册。

函数内部注册

在Vue.js中,以camelCase声明并以‘v’为前缀的变量会自动被识别为指令。在上面的示例中,我们定义了 v-text-color 指令,它接受绑定的元素并根据提供的值设置文本颜色。

<script setup>
import { ref } from 'vue'

const msg=ref('Hello World!')

const vTextColor={
  mounted: (el,binding)=> el.style.color=binding.value
}
</script>

<template>
  <h1 v-text-color="`green`">{{ msg }}</h1>
  <input v-model="msg">
</template>

函数外部注册

我们还可以使用 directives API选项在setup函数之外注册指令。下面的代码片段演示了如何实现这一点。


export default {
  setup() {
    /*...*/
  },
  directives: {
    // enables v-textcolor in template
    textcolor: {
      /* ... */
    }
  }
}

全局注册

对于您打算在整个应用程序中经常重复使用的指令,建议将其全局注册,如下所示:

const app=createApp({})

// make v-textcolor usable in all components
app.directive('textcolor', {
  /* ... */
})

创建我们的自定义URL清理指令

既然我们已经探索了在Vue.js中注册自定义指令的不同方法,那么让我们继续创建一个安全地清理提供的URL的指令。为了避免重复造轮子并确保URL解析的稳健性,我们将利用 @braintree/sanitize-url 包。该包经过了广泛的测试,在开发者中得到了广泛的采用,并且正在积极维护。

本质上,该指令的目的是获取绑定的元素的值,即一个URL,并对其进行清理,确保其安全性。根据您偏好的软件包管理器,您可以安装'@braintree/sanitize-url'。在本示例中,我们将使用npm。

npm install -S @braintree/sanitize-url

Unsafe URL

这是一个我们旨在清理的不安全URL的示例。

http://example.com/login?redirect=http://malicious-site.com/attack?payload=<script>alert('XSS Attack');</script>

在这个例子中:

  • 该URL似乎是一个登录页面(http://example.com/login),带有一个重定向的查询参数。
  • 重定向参数指向一个潜在的恶意网站(http://malicious-site.com/attack),并包含一个可能执行跨站脚本攻击(XSS)的有效负载()。

我们自定义的URL清洗器

<script setup>
import { ref } from 'vue'
import { sanitizeUrl } from '@braintree/sanitize-url'

const  msg=ref('Hello World!')
const url=ref('http://example.com/login?redirect=http://malicious-site.com/attack?payload=<script>alert('XSS Attack');</script>
')

const vSafeUrl={
  mounted:(el,binding)=> {
    el.setAttribute('href', sanitizeUrl(binding.value))
    }
}
</script>

<template>
  <h1>{{ msg }}</h1>
  <a v-safe-url="`url`">Safe url</a>
</template>

结束

在Vue.js中对自定义指令的探索强调了它们在根据特定需求定制应用程序方面的出色适应性和实用性。本文中我们还了解了各种指令注册方法,体现了Vue在定义其范围和可重用性方面的灵活性。

由于文章内容篇幅有限,今天的内容就分享到这里,文章结尾,我想提醒您,文章的创作不易,如果您喜欢我的分享,请别忘了点赞和转发,让更多有需要的人看到。同时,如果您想获取更多前端技术的知识,欢迎关注我,您的支持将是我分享最大的动力。我会持续输出更多内容,敬请期待。