虽然已经和 javascript 打交道很长时间了,但有时可能没有更新最新的特性,这些特性可以解决日常的一些问题,而不需要编写额外的代码。
在这里,收集总结了编写优雅代码的经验,对代码优化及 review 有一定的帮助。
1、如何在 JavaScript 中检查空字符串/undefined/null?
判断一个变量是否为空字符串、undefined、null,在与后台 API 联调时特别常见。
!!data
const items = ["", null, undefined];for (const item of items) { console.log(!!item);}
复制代码
使用类型转换 Boolean(data)
const items = ["", null, undefined];for (const item of items) { console.log(Boolean(item));}
复制代码
两种方法实现了相同的功能,将变量类型转换为布尔值。
2、小数四舍五入
这里列举四种实现方式
parseFloat
parseFloat() 函数解析一个参数(必要时先转换为字符串)并返回一个浮点数。
const FLOOR_NUMBER = 3.141592653;console.log(parseFloat(FLOOR_NUMBER).toFixed(2)); // 3.14
复制代码
Math.round
Math.round() 函数返回一个数字四舍五入后最接近的整数。
const FLOOR_NUMBER = 3.141592653;console.log(Math.round(FLOOR_NUMBER * 100 + Number.EPSILON) / 100);
复制代码
Number() 构造函数创建一个 Number 对象。
将字符串转换为十进制
const FLOOR_NUMBER = 3.141592653;const strNumber = FLOOR_NUMBER.toFixed(2); // => '3.14'console.log(Number(strNumber)); // => 3.14
复制代码
使用 Lodash
const _ = require("lodash");const FLOOR_NUMBER = 3.141592653;console.log(_.floor(FLOOR_NUMBER, 2));
复制代码
3、对象数组按照指定 key 排序
实现的方式有几种,这里列举三种供参考
使用 Lodash
Lodash 是一个一致性、模块化、高性能的 javascript 实用工具库,俗称下划线 _。
_.sortBy(collection, [iteratees=[_.identity]])
复制代码
创建一个元素数组。 以 iteratee 处理的结果升序排序。 这个方法执行稳定排序,也就是说相同元素会保持原始排序。 iteratees 调用 1 个参数: (value)。
const _ = require("lodash");var users = [ { user: "fred", age: 48 }, { user: "barney", age: 36 }, { user: "fred", age: 40 }, { user: "barney", age: 34 },];
_.sortBy(users, function (o) { return o.user;}); // 结果为: [{ user: 'barney', age: 36 },{ user: 'barney', age: 34 },{ user: 'fred', age: 48 },{ user: 'fred', age: 40 }]
_.sortBy(users, ["user", "age"]); // 结果为: [{ user: 'barney', age: 34 },{ user: 'barney', age: 36 },{ user: 'fred', age: 40 },{ user: 'fred', age: 48 }]
_.sortBy(users, "user", function (o) { return Math.floor(o.age / 10);}); // 结果为: [{ user: 'barney', age: 36 },{ user: 'barney', age: 34 },{ user: 'fred', age: 48 },{ user: 'fred', age: 40 }]
复制代码
使用 ES6
var users = [ { user: "fred", age: 48 }, { user: "barney", age: 36 }, { user: "fred", age: 40 }, { user: "barney", age: 34 },];
// 按照age排序const result = users.sort(function (a, b) { return a.age - b.age;});console.log(result); // [{ user: 'barney', age: 34 }, { user: 'barney', age: 36 },{ user: 'fred', age: 40 },{ user: 'fred', age: 48 }]
复制代码
4、对象遍历
每个 ECMAScript 版本都采用不同的方式遍历对象。
ES5 可以使用以下方法
const myinfo = { name: "devpoint", city: "Shenzhen" };Object.keys(myinfo).forEach((key) => { console.log(key, "=", myinfo[key]);});
复制代码
ES6 中可以使用 for...of
for...of语句在可迭代对象(包括 Array,Map,Set,String,TypedArray,arguments 对象等等)上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句。
const myinfo = { name: "devpoint", city: "Shenzhen" };
for (const key of Object.keys(myinfo)) { console.log(key, "=", myinfo[key]);}
复制代码
ES8 使用Object.entries()
Object.entries() 方法返回一个给定对象自身可枚举属性的键值对数组,其排列与使用 for...in 循环遍历该对象时返回的顺序一致(区别在于 for-in 循环还会枚举原型链中的属性)。
Object.entries(myinfo).forEach(([key, value]) => console.log(key, "=", value));
复制代码
也可以这样:
for (const [key, value] of Object.entries(myinfo)) { console.log(key, "=", value);}
复制代码
使用 Lodash
const _ = require("lodash");const myinfo = { name: "devpoint", city: "Shenzhen" };
_.forEach(myinfo, (value, key) => { console.log(key, "=", value);});
复制代码
5、event.stopPropagation()、event.preventDefault() 和 return false 区别
event.stopPropagation() 阻止事件的冒泡方法,不让事件向 documen上蔓延,但是默认事件任然会执行,当你掉用这个方法的时候,如果点击一个连接,这个连接仍然会被打开;
event.preventDefault() 阻止默认事件的方法,调用此方法是,连接不会被打开,但是会发生冒泡,冒泡会传递到上一层的父元素;
return false 比较暴力,会同时阻止事件冒泡也会阻止默认事件;写上此代码,连接不会被打开,事件也不会传递到上一层的父元素;可以理解为return false就等于同时调用了event.stopPropagation() 和event.preventDefault()
$(".header a").click(function (e) { event.stopPropagation(); //不会打印 devpoint ,但是页面会跳转;});$(".header").click(function () { console.log("devpoint"); });
复制代码
$(".header").click(function () { console.log("devpoint"); });$(".header a").click(function (e) { event.preventDefault(); // 页面不会跳转,但会打印 devpoint;});
复制代码
6、如何获取当前 url
这是比较常见的,使用方法:window.location.href
7、如何判断对象是否存在某个 KEY?
如判断对象中是否存在键值:title
使用操作符
const info = { title: "devpoint",};const detail = { content: "Hello",};const find = "title";const result = find in info;const result2 = find in detail;console.log(result); // trueconsole.log(result2); // false
复制代码
使用hasOwnProperty
const info = { title: "devpoint",};const detail = { content: "Hello",};const find = "title";const result = info.hasOwnProperty(find);const result2 = info.hasOwnProperty(detail);console.log(result); // trueconsole.log(result2); // false
复制代码
直接读取 key 值
const info = { title: "devpoint",};const detail = { content: "Hello",};const find = "title";const result = info[find] !== undefined;const result2 = detail[find] !== undefined;console.log(result); // trueconsole.log(result2); // false
复制代码
8、 如何插入元素到数组指定索引位置?
在特定索引位置附加 1 个元素,这里讨论的问题排除头部和尾部的情况,如在索引为2后面插入元素devpoint
const items = ["info", "name", "age", "day"];const insertItem = "devpoint";items.splice(2, 0, insertItem);console.log(items); // [ 'info', 'name', 'devpoint', 'age', 'day' ]
复制代码
附加多个元素,也是适用的。
const items = ["info", "name", "age", "day"];const insert1 = "devpoint";const insert2 = "https";items.splice(2, 0, insert1, insert2);console.log(items); // [ 'info', 'name', 'devpoint', 'https', 'age', 'day' ]
复制代码
将 1 个数组所有元素附加到指定索引后面,如下:
const items = ["info", "name", "age", "day"];const news = ["devpoint", "https"];items.splice(2, 0, ...news);console.log(items); // [ 'info', 'name', 'devpoint', 'https', 'age', 'day' ]
复制代码
9、如何合并两个数组并删除重复项?
在开发中,合并数组并删除重复项是比较常见的需求。
使用 Lodash
const _ = require("lodash");const item1 = [2021, 2022, 2023];const item2 = [2019, 2020, 2021];const newItem = _.union(item1, item2);console.log(newItem); // [ 2021, 2022, 2023, 2019, 2020 ]
复制代码
使用数组方法filter和contact
const item1 = [2021, 2022, 2023];const item2 = [2019, 2020, 2021];
const tmpItem = item1.concat(item2); // [ 2021, 2022, 2023, 2019, 2020, 2021 ]const newItem = tmpItem.filter((val, pos) => tmpItem.indexOf(val) === pos); // [ 2021, 2022, 2023, 2019, 2020 ]
复制代码
使用set
const item1 = [2021, 2022, 2023];const item2 = [2019, 2020, 2021];
const newItem = [...new Set([...item1, ...item2])]; // [ 2021, 2022, 2023, 2019, 2020 ]
复制代码
10、如何在字符串中查找字符并替换为空?
使用replace
let str = "developpoint";const findStr = "elop";str = str.replace(findStr, ""); // devpointconsole.log(str);
复制代码
使用正则表达式
let str = "developpoint";const findStr = "elop";str = str.replace(new RegExp(findStr), "");
复制代码
11、如何在数组中追加新的元素?
在过去的 JavaScript 版本中,是通过使用apply方法来实现的。
const item1 = [2021, 2022, 2023];const item2 = [2019, 2020];
Array.prototype.push.apply(item2, item1);console.log(item2); // [ 2019, 2020, 2021, 2022, 2023 ]
复制代码
使用 ES6
const item1 = [2021, 2022, 2023];const item2 = [2019, 2020];
item2.push(...item1);console.log(item2); // [ 2019, 2020, 2021, 2022, 2023 ]
复制代码
12、如何判断一个对象是否为数组?
判断一个对象是否为数组,使用场景也是比较常见的,同样可以使用Lodash,这里不做详细介绍了,有兴趣可以去看看文档。
在 ES6 之前的版本可以通过下面的方式来判断是否为数组(可以兼容旧的浏览器),为了方便,三种方式写在一起。
const arrayYears = [2021, 2022, 2023];const objYears = { value: "2021" };
const isArray = (() => { return { byInstanceof: (array) => { return array instanceof Array; }, byConstructor: (array) => { return array.constructor.toString().indexOf("Array") > -1; }, byPrototype: (array) => { return Object.prototype.toString.call(array) === "[object Array]"; }, };})();
console.log(isArray.byInstanceof(arrayYears)); // trueconsole.log(isArray.byConstructor(arrayYears)); // trueconsole.log(isArray.byPrototype(arrayYears)); // true
console.log(isArray.byInstanceof(objYears)); // falseconsole.log(isArray.byConstructor(objYears)); // falseconsole.log(isArray.byPrototype(objYears)); // false
复制代码
使用 ES6
使用 ES6 就简洁多了。
const arrayYears = [2021, 2022, 2023];const objYears = { value: "2021" };
const isArray = (array) => { return Array.isArray(array);};console.log(isArray(arrayYears)); // trueconsole.log(isArray(objYears)); // false
复制代码
13、如何解析 URL 中的参数?
当在处理 URL 的时候,经常遇到需要解析 URL 中的参数,并获取其值。
使用正则
const getQueryStringParams = (query) => { return query ? (/^[?#]/.test(query) ? query.slice(1) : query) .split("&") .reduce((params, param) => { const [key, value] = param.split("="); params[key] = value ? decodeURIComponent(value.replace(/\+/g, " ")) : ""; return params; }, {}) : {};};const params = getQueryStringParams("?wd=devpoint"); // { wd: 'devpoint' }console.log(params); // { wd: 'devpoint' }
复制代码
使用 URLSearchParams
URLSearchParams 接口定义了一些实用的方法来处理 URL 的查询字符串。拥有包括append、delete、entries等方法,详见介绍。
const getQueryStringParams = (strUrl) => { return new URL(strUrl).searchParams;};const url = "https://www.baidu.com/s/?wd=devpoint";const params = getQueryStringParams(url); // URLSearchParams { 'wd' => 'devpoint' }console.log(params.get("wd")); // devpoint
复制代码
14、如何获取对象的长度(key 数量)?
大部份情况下,我们会检查数组的长度,但如果要获取对象的长度呢?下面两种方法是获取对象长度的最佳方法。
使用 Lodash
const _ = require("lodash");const obj = { title: "devpoint", city: "Shenzhen", type: "blog",};const objSize = _.size(obj);console.log(objSize); // 3
复制代码
使用 ES6
const obj = { title: "devpoint", city: "Shenzhen", type: "blog",};const objSize = Object.keys(obj).length;console.log(objSize); // 3
复制代码
15、如何将字符串转换为对象数组?
当从无法控制的第三方 API 获取一些数据时,就会出现这种情况。如何将字符串转换为对象数组以在应用程序中更好的使用?以下是获得此结果的最简单方法。
const apiData = "Option 1|false|Option 2|false|Option 3|false|Option 4|true";
const formatToArray = (str) => { return str.split("|").reduce((arrayResult, item, index, arrData) => { if (index % 2 === 0) { const [option, value] = [item, JSON.parse(arrData[index + 1])]; arrayResult.push({ option, value }); } return arrayResult; }, []);};console.log(formatToArray(apiData));
复制代码
输出的数据格式为:
[ { option: 'Option 1', value: false }, { option: 'Option 2', value: false }, { option: 'Option 3', value: false }, { option: 'Option 4', value: true }]
复制代码
javascript 的灵活性,使得编写优雅的代码方法多种多样,需要去深入研究并总结,今天的分享就到此。
评论