虽然已经和 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); // true
console.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); // true
console.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); // true
console.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, ""); // devpoint
console.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)); // true
console.log(isArray.byConstructor(arrayYears)); // true
console.log(isArray.byPrototype(arrayYears)); // true
console.log(isArray.byInstanceof(objYears)); // false
console.log(isArray.byConstructor(objYears)); // false
console.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)); // true
console.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 的灵活性,使得编写优雅的代码方法多种多样,需要去深入研究并总结,今天的分享就到此。
评论