JavaScript 杀手级语句
为了提高你的 JavaScript 知识与技能,你应该了解一些JavaScript的单行代码技巧。JavaScript中有很多速记技巧,可以缩短代码长度,减少冗余,提高代码的可读性和可维护性
文章目录
- 1.复制内容到剪贴板
- 2.获取鼠标选择
- 3.打乱数组
- 4. 将rgba转换为十六进制
- 5.十六进制转换为rgba
- 6.获取多个数的平均值
- 7.检查数字是偶数还是奇数
- 8.删除数组中的重复元素
- 9.检查一个对象是否为空对象
- 10.反转字符串
- 11.计算两个日期之间的间隔
- 12.查找该日期是一年中的第几天
- 13.将字符串的第一个字母大写
- 14.生成指定长度的随机字符串
- 15.获取两个整数之间的随机整数
- 16.指定数字四舍五入
- 17.清除所有cookie
- 18.检测是否为深色模式
- 19.滚动到页面顶部
- 20.判断是否为苹果设备
- 21.随机布尔值
- 22.获取变量的类型
- 23.判断当前选项卡是否处于活动状态
- 24. 检查某个元素是否获得焦点
- 25.随机IP
- 26.从数组中删除假值
- 27.数组搜索
- 28.空值合并运算符
- 29.逻辑或赋值运算符
- 30.多值匹配
- 31.三元表达式
- 32.短路评估
- 33.科学计数法
- 34.位运算符
- 35.指数求幂
- 36.双非运算符
- 37.对象属性
- 38.箭头函数
- 39.参数解构
- 40.扩展运算符
- 41.强制参数
- 42.转换为布尔值
- 43.变量交换
- 44.变量声明
- 45.For循环
1.复制内容到剪贴板
为了提高网站的用户体验,我们经常需要将内容复制到剪贴板,以便用户粘贴到指定的地方。
const copyToClipboard = (content) => navigator.clipboard.writeText(content)
copyToClipboard("Hello fatfish")
2.获取鼠标选择
您以前遇到过这种情况吗?
我们需要获取用户选择的内容。
const getSelectedText = () => window.getSelection().toString()
getSelectedText()
3.打乱数组
打乱数组?这在彩票项目中很常见,但它并不是真正随机的。
const shuffleArray = array => array.sort(() => Math.random() - 0.5)
shuffleArray([ 1, 2,3,4, -1, 0 ]) // [3, 1, 0, 2, 4, -1]
4. 将rgba转换为十六进制
我们可以将 RGBA 和十六进制颜色值相互转换。
const rgbaToHex = (r, g, b) => "#" + [r, g, b].map(num => parseInt(num).toString(16).padStart(2, '0')).join('')
rgbaToHex(0, 0 ,0) // #000000
rgbaToHex(255, 0, 127) //#ff007f
5.十六进制转换为rgba
const hexToRgba = hex => {
const [r, g, b] = hex.match(/\w\w/g).map(val => parseInt(val, 16))
return `rgba(${r}, ${g}, ${b}, 1)`;
}
hexToRgba('#000000') // rgba(0, 0, 0, 1)
hexToRgba('#ff007f') // rgba(255, 0, 127, 1)
6.获取多个数的平均值
使用reduce我们可以非常方便的得到一组数组的平均值。
const average = (...args) => args.reduce((a, b) => a + b, 0)
average(0, 1, 2, -1, 9, 10) // 3.5
7.检查数字是偶数还是奇数
如何判断一个数是奇数还是偶数?
const isEven = num => num % 2 === 0
isEven(2) // true
isEven(1) // false
8.删除数组中的重复元素
要删除数组中的重复元素,使用 Set 将变得非常容易。
const uniqueArray = (arr) => [...new Set(arr)]
uniqueArray([ 1, 1, 2, 3, 4, 5, -1, 0 ]) // [1, 2, 3, 4, 5, -1, 0]
9.检查一个对象是否为空对象
判断一个对象是否为空容易吗?
const isEmpty = obj => Reflect.ownKeys(obj).length === 0 && obj.constructor === Object
isEmpty({}) // true
isEmpty({ name: 'fatfish' }) // false
10.反转字符串
const reverseStr = str => str.split('').reverse().join('')
reverseStr('fatfish') // hsiftaf
11.计算两个日期之间的间隔
const dayDiff = (d1, d2) => Math.ceil(Math.abs(d1.getTime() - d2.getTime()) / 86400000)
dayDiff(new Date("2023-06-23"), new Date("1997-05-31")) // 9519
12.查找该日期是一年中的第几天
今天是2023年6月23日,那么今年是什么日子呢?
const dayInYear = (d) => Math.floor((d - new Date(d.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24)
dayInYear(new Date('2023/06/23'))// 174
13.将字符串的第一个字母大写
const capitalize = str => str.charAt(0).toUpperCase() + str.slice(1)
capitalize("hello fatfish") // Hello fatfish
14.生成指定长度的随机字符串
const generateRandomString = length => [...Array(length)].map(() => Math.random().toString(36)[2]).join('')
generateRandomString(12) // cysw0gfljoyx
generateRandomString(12) // uoqaugnm8r4s
15.获取两个整数之间的随机整数
const random = (min, max) => Math.floor(Math.random() * (max - min + 1) + min)
random(1, 100) // 27
random(1, 100) // 84
random(1, 100) // 55
16.指定数字四舍五入
const round = (n, d) => Number(Math.round(n + "e" + d) + "e-" + d)
round(3.1415926, 3) //3.142
round(3.1415926, 1) //3.1
const clearCookies = document.cookie.split(';').forEach(cookie => document.cookie = cookie.replace(/^ +/, '').replace(/=.*/, `=;expires=${new Date(0).toUTCString()};path=/`))
18.检测是否为深色模式
const isDarkMode = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
console.log(isDarkMode)
19.滚动到页面顶部
const goToTop = () => window.scrollTo(0, 0)
goToTop()
20.判断是否为苹果设备
const isAppleDevice = () => /Mac|iPod|iPhone|iPad/.test(navigator.platform)
isAppleDevice()
21.随机布尔值
const randomBoolean = () => Math.random() >= 0.5
randomBoolean()
22.获取变量的类型
const typeOf = (obj) => Object.prototype.toString.call(obj).slice(8, -1).toLowerCase()
typeOf('') // string
typeOf(0) // number
typeOf() // undefined
typeOf(null) // null
typeOf({}) // object
typeOf([]) // array
typeOf(0) // number
typeOf(() => {}) // function
23.判断当前选项卡是否处于活动状态
const checkTabInView = () => !document.hidden
24. 检查某个元素是否获得焦点
const isFocus = (ele) => ele === document.activeElement
25.随机IP
const generateRandomIP = () => {
return Array.from({length: 4}, () => Math.floor(Math.random() * 256)).join('.');
}
generateRandomIP() // 220.187.184.113
generateRandomIP() // 254.24.179.151
26.从数组中删除假值
您可以使用 filter() 组合布尔值来简化从数组中删除假值的过程。false 值是指将 false 视为条件的值,例如 null、未定义、空字符串(“”或 ”)、0、NaN 和 false。
传统写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(value => {
if(value) {
return value
};
});
// [12, 'xyz', -25, 0.5]
简化写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(value => Boolean(value)); // [12, 'xyz', -25, 0.5]
更简化的写法:
let arr = [12, null, 0, 'xyz', null, -25, NaN, '', undefined, 0.5, false];
let filterArray = arr.filter(Boolean); // [12, 'xyz', -25, 0.5]
Boolean 是 JavaScript 的内置构造函数,通过将值传递给它来将值转换为布尔值。在本例中,Boolean 构造函数作为回调函数传递给 filter() 方法,从而将每个数组元素转换为布尔值。只有转换结果为 true 的元素才会保留在新数组中。
注意:该方法也会过滤掉0。如果不需要过滤掉0,则需要额外判断。
27.数组搜索
当搜索数组时,indexOf()用于获取搜索项的位置。如果未找到该项目,则返回值为-1。在 JavaScript 中,0 被视为 false,大于或小于 0 的数字被视为 true。因此,需要这样写:
传统写法:
if(arr.indexOf(item) > -1) {
}
if(arr.indexOf(item) === -1) {
}
简化写法:
if(~arr.indexOf(item)) {
}
if(!~arr.indexOf(item)) {
}
按位 NOT (~) 运算符对于除 -1 之外的任何值都返回“真”值。要否定它,只需使用 !~ 即可。或者,您可以使用includes()函数:
if(arr.includes(item)) {
}
28.空值合并运算符
null 合并运算符 (??) 用于为 null 或 .undefined 的变量提供默认值
传统写法:
const fetchUserData = () => {
return 'Xiuer Old';
};
const data = fetchUserData();
const username = data !== null && data !== undefined ? data : 'Guest';
简化写法:
const fetchUserData = () => {
return 'Xiuer Old';
};
const data = fetchUserData();
const username = data ?? 'medium';
另外,还有一个空合并赋值运算符(??=),用于当变量为空(null或undefined)时执行赋值操作。
传统写法:
let variable1 = null;
let variable2 = "Xiuer Old";
if (variable1 === null || variable1 === undefined) {
variable1 = variable2;
}
简化写法:
let variable1 = null;
let variable2 = "Xiuer Old";
variable1 ??= variable2;
??=写法更简洁,更容易阅读。它首先检查变量 1 是否为 null 或未定义,如果是,则将值赋给变量 2。如果variable1已经有一个非空值,则不会发生赋值。
29.逻辑或赋值运算符
逻辑或赋值运算符 (||=) 用于为变量指定默认值。
传统写法:
let count;
if (!count) {
count = 0;
}
简化写法:
let count;
count ||= 0;
当 count 为假值(例如 undefined、null、false、0、NaN 或空字符串)时,逻辑 OR 赋值运算符将赋值 0。count 否则,它保留 count 的原始值。
30.多值匹配
对于多个值的匹配,可以将所有值放入一个数组中,然后使用indexOf()方法进行检查。indexOf() 方法是 JavaScript 数组的内置方法,用于返回指定元素在数组中第一次出现的位置索引。如果数组中不存在该元素,则返回-1。
传统写法:
if (value === 1 || value === 'one' || value === 2 || value === 'two') {
// ...
}
简化写法:
if ([1, 'one', 2, 'two'].indexOf(value) >= 0) {
// ...
}
31.三元表达式
这可以使用三元表达式 if…else 来简化。
传统写法:
let isAdmin;
if (user.role === 'admin') {
isAdmin = true;
} else {
isAdmin = false;
}
简化写法:
const isAdmin = user.role === 'admin' ? true : false;
更简化的写法:
const isAdmin = user.role === 'admin';
32.短路评估
将一个变量的值分配给另一个变量时,您可能需要确保源变量不为 null、未定义或为空。您可以编写包含多个条件的长 if 语句,或使用短路求值来简化。
if (variable1 !== null || variable1 !== undefined || variable1 !== '') {
let variable2 = variable1;
}
使用短路评估简化的代码如下:
const variable2 = variable1 || 'new';
对于逻辑 OR (||) 运算符,以下值被视为 false:
- false
- 0
- 空字符串(“”或“”)
- null
- undefined
- NaN
因此,如果值本身可能是其中之一,则不适合使用短路评估。
短路评估还可以避免函数调用中不必要的函数执行。
传统写法:
function fetchData() {
if (shouldFetchData) {
return fetchDataFromAPI();
} else {
return null;
}
}
简化写法:
function fetchData() {
return shouldFetchData && fetchDataFromAPI();
}
当 shouldFetchData 为 true 时,短路评估继续执行函数的 fetchDataFromAPI() 并返回其结果。如果shouldFetchData为假值,短路求值将直接返回假值(null),避免不必要的函数调用。
33.科学计数法
可以使用科学和技术方法来表示数字以省略尾随零。例如,1e7it 实际上意味着 1 后面跟着 7 个零。它代表 10,000,000 的十进制等值。
传统写法:
for (let i = 0; i < 10000; i++) {}
简化写法:
for (let i = 0; i < 1e7; i++) {}
// 下面的所有比较都将返回 true
1e0 === 1;
1e1 === 10;
1e2 === 100;
1e3 === 1000;
1e4 === 10000;
1e5 === 100000;
34.位运算符
双位 NOT 运算符有一个非常实际的用途,您可以用它来替换 Math.floor() 函数,在执行相同操作时速度更快。
传统写法:
Math.floor(4.9) === 4 //true
简化写法:
~~4.9 === 4 //true
35.指数求幂
指数求幂运算可以使用 * 来简化。
传统写法:
Math.pow(2,3); // 8
Math.pow(2,2); // 4
Math.pow(4,3); // 64
简化写法:
2**3 // 8
2**4 // 4
4**3 // 64
从ES7(ECMAScript 2016)开始,JavaScript引入了指数幂运算符**,使指数幂运算更加简洁。
36.双非运算符
在 JavaScript 中,双非按位运算符 ~~ 可用于对数字进行向下舍入,类似于 Math.floor() 方法的功能。
传统写法:
const floor = Math.floor(6.8); // 6
简化写法:
const floor = ~~6.8; // 6
注:双非位运算符仅适用于 32 位整数,即范围为 -(231) 到 (231)-1,即 -2147483648 到 2147483647。双非位运算符 ( ~~ ) 对于大于 2147483647 或小于 0 的数字给出不正确的结果,因此建议在这种情况下使用 Math.floor() 方法。
37.对象属性
ES6 提供了一种更简单的方法来为对象分配属性。如果变量名与对象的键名相同,则可以使用缩写表示法进行赋值。
传统写法:
const name = 'web前端开发';
const age = 18;
const person = {
name: name,
age: age
};
简化写法:
const name = 'jie';
const age = 30;
const person = {
name,
age
};
38.箭头函数
箭头函数可以简化经典函数的编写。
传统写法:
function sayHello(name) {
console.log('Hello', name);
}
setTimeout(function() {
console.log('Loaded')
}, 2000);
list.forEach(function(item) {
console.log(item);
});
简化写法:
sayHello = name => console.log('Hello', name);
setTimeout(() => console.log('Loaded'), 2000);
list.forEach(item => console.log(item));
如果箭头函数只有一条语句,它将隐式返回其计算结果,并且 returnthe 关键字可以省略:
传统写法:
function calcCircumference(diameter) {
return Math.PI * diameter
}
简化写法:
calcCircumference = diameter => (
Math.PI * diameter;
)
39.参数解构
如果使用一些流行的 Web 框架,例如 React 和 Vue,可以使用数组或对象文字形式的数据在组件之间传递信息。要在组件中使用数据对象,需要对它们进行解构。
传统写法:
const observable = require('mobx/observable');
const action = require('mobx/action');
const runInAction = require('mobx/runInAction');
const store = this.props.store;
const form = this.props.form;
const loading = this.props.loading;
const errors = this.props.errors;
const entity = this.props.entity;
简化写法
import { observable, action, runInAction } from 'mobx';
const { store, form, loading, errors, entity } = this.props;
还可以为变量指定新的变量名称:
const { store, form, loading, errors, entity:contact } = this.props;
40.扩展运算符
ES6中引入的扩展运算符可以简化一些对数组和对象的操作。
传统写法:
// Merge arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6].concat(odd);
// Clone an array
const arr = [1, 2, 3, 4];
const arr2 = arr.slice();
简化写法:
// Merge arrays
const odd = [1, 3, 5];
const nums = [2, 4, 6, ...odd];
console.log(nums); // [ 2, 4, 6, 1, 3, 5 ]
// Clone an array
const arr = [1, 2, 3, 4];
const arr2 = [...arr];
与 concat() 函数不同,可以使用展开运算符将一个数组插入到另一个数组中的任意位置。
const odd = [1, 3, 5];
const nums = [2, ...odd, 4, 6];
你还可以将扩展运算符与 ES6 的解构语法结合使用:
const { a, b, ...z } = { a: 1, b: 2, c: 3, d: 4 };
console.log(a) // 1
console.log(b) // 2
console.log(z) // { c: 3, d: 4 }
扩展运算符还可以用于合并对象:
传统写法:
let fname = { firstName : 'medium' };
let lname = { lastName : 'xiuer'}
let full_names = Object.assign(fname, lname);
简化写法:
let full_names = {...fname, ...lname};
41.强制参数
在传统的JavaScript编写中,为了确保函数参数传入一个有效的值,我们需要使用条件语句来抛出错误。通过使用强制参数缩写可以实现相同的逻辑。
传统写法:
function foo(bar) {
if(bar === undefined) {
throw new Error('Missing parameter!');
}
return bar;
}
简化写法:
mandatory = () => {
throw new Error('Missing parameter!');
}
foo = (bar = mandatory()) => {
return bar;
}
这里定义了一个名为强制的函数,抛出错误,表明函数参数没有传入。然后,在 foo 函数的参数列表中,使用分配默认值的方法将参数设置为强制()调用 结果。如果 bar 没有传入参数或者传入了 false 值,会触发 Mustadal() 函数的执行。
42.转换为布尔值
使用双逻辑 NOT 运算符可以将任何值转换为布尔值。
!!23 // TRUE
!!"" // FALSE
!!0 // FALSE
!!{} // TRUE
单个逻辑 NOT 运算符已经可以将值转换为布尔类型并对它取反,因此,第二个逻辑 NOT 运算符再次对其取反,将其返回到其原始含义并将其保留为布尔类型。
43.变量交换
使用数组解构可以轻松实现变量交换。
传统写法(使用临时变量完成两个变量的交换):
let a = 5;
let b = 10;
const temp = a;
a = b;
b = temp;
简化写法(使用数组解构赋值完成两个变量的交换):
let a = 5;
let b = 10;
[a, b] = [b, a];
这里我们创建一个包含两个元素[b, a]的数组,然后,使用数组解构赋值将值分别赋给变量a和b。由于左边的数组和右边的数组结构相同,所以交换两个值。
44.变量声明
当需要同时声明多个变量时,可以使用变量声明的简写方法,以节省时间和空间。
传统写法:
let x;
let y;
let z = 3;
简化写法:
let x, y, z = 3;
不过,这种优化存在一些争议。很多人认为这样写会影响代码的可读性,因为一行写了很多变量,不如一行一个变量那么清晰,所以可以有选择地采用。
如果有多个变量需要赋予相同的值,可以使用连续相等来实现。
传统写法:
let a = 100;
let b = 100;
let c = 100;
简化写法:
let a = b = c = 100;
45.For循环
JavaScript 中传统的 for 循环语法使用数组的长度作为迭代器来遍历数组。 还有许多 for 循环快捷方式提供了迭代数组中对象的不同方式,例如:
for…of:用于遍历内置字符串、数组、类数组对象、NodeList。
for…in:一个字符串,用于访问数组的索引并遍历对象字面量,并记录属性名称和值。
Array.forEach:使用回调函数对数组元素及其索引执行操作。
传统写法:
for (let i = 0; i < arr.length; i++) {
console.log("item: ", arr[i]);}
}
简化写法:
for (let str of arr) {
console.log("item: ", str);
}
arr.forEach((str) => {
console.log("item: ", str);
});
for (let index in arr) {
console.log(index, arr[index]);
}
对于对象字面量,还可以使用 for…in 来遍历:
const obj = { a: 1, b: 3, c: 5 };
for (let key in obj) {
console.log(key, obj[key]);
}