基础回顾(二)
接下来的时间,我会总结几篇js基础知识的文章。可能这些知识点都是老生常谈,网上一搜一大堆。但只有把基础知识打牢,才能在programing这条路上走的更远。一定要理解前端领域的变与不变,不能一味地追逐热门。
数组去重
//原数组上操作
//思路:判断数组中每个元素是否与后一个元素相等,如果相等,就使用splice()删除后面的元素
function dup1(arr) {
for (var i = 0; i < arr.length; i++) {
for (var j = i + 1; j < arr.length; j++) {
if (arr[i] === arr[j]) {
arr.splice(j,1);
j--;
}
}
}
return arr;
}
//新数组
//思路:遍历原数组,使用indexOf判断新数组是否包含原数组的每一项,如果没有就push进新数组
function dup2(arr) {
var newArr = [];
for (var i = 0; i < arr.length; i++) {
if (newArr.indexOf(arr[i]) == -1) {
newArr.push(arr[i]);
}
}
return newArr;
}
//使用对象
//思路: 把数组的值存为object的key值,去对象中访问属性
function dup3(arr) {
var newArr = [];
var obj = {};
for (var i = 0; i < arr.length; i++) {
if (!obj[arr[i]]) {
newArr.push(arr[i]);
obj[arr[i]] = 1;
}
}
return newArr;
// return arr.filter(function(item, index, arr) {
// return obj.hasOwnProperty(item) ? false : (obj[item] = true);
// })
}
//使用filter
function dup4(arr) {
var filterArr = arr.filter(function(item, index, arr) {
return arr.indexOf(item) === index;
})
return filterArr;
}
//箭头函数写法
const filterArr = (arr) => {
return arr.filter((item, index, arrCurrent) => arrCurrent.indexOf(item) === index)
}
//ES6 set
function dup5(arr) {
// 也可以使用展开运算符
return Array.from(new Set(arr)) || [...new Set(arr)]
}
实现multiply()方法
描述:const a = [1, 2, 3, 4, 5]; a.multiply(); => [1, 2, 3, 4, 5, 1, 4, 9, 16, 25]
// 方法1 => not good,没有按照要求
let multiply = function(arr) {
let multiplyArr = arr.map(num => num * num);
return arr.concat(multiplyArr);
};
const a = [1, 2, 3, 4, 5];
multiply(a);
// 方法2 => not bad,直接在数组原型上添加方法
Array.prototype.multiply = function() {
let multiplyArr = this.map(num => num * num);
this.push(...multiplyArr);
}
// 方法3 => good,在对象上添加方法
const pushArr = function(arr, num) {
arr.push(num * num);
return arr;
}
a.multiply = function() {
return this.reduce(pushArr, this);
}
// 方法4 => very good,使用ES6,语句更简洁
a.multiply = () => [...a, ...a.map(num => num * num)];
实现extname()描述
描述:对于给定的文件名返回它的拓展名,如emoji.png => .png
// 找到文件名的最后一个『.』,然后返回后面的字符串内容
function extname(filename) {
return filename.lastIndexOf('.') > 0 ? filename.slice(filename.lastIndexOf('.')) : '';
}
实现flattened()方法
描述:对多维数组进行降维操作,如[[1, 2],[3, 4]] => [1, 2, 3, 4]
// 方法1 => 递归
function flattened1(arr) {
let flattenedArr = [];
// 循环传入的数组元素
arr.map(function(item) {
// 如果还是一个数组,就递归调用该方法
if (Array.isArray(item)) {
flattenedArr = flattenedArr.concat(flattened(item));
} else {
flattenedArr.push(item);
}
})
return flattenedArr;
}
// 方法2 => toString()
// 限制:数组元素只能为数字
function flattened2(arr) {
arr.toString().split(',').map(function(item) {
// 类型转换
return +item;
})
}
// 方法3 => reduce
// 限制:只能降二维的数组
function flattened3(arr) {
return arr.reduce((acc, cur) => acc.concat(cur),[]);
}
// 方法3改进版
function flattened3(arr) {
return arr.reduce((acc, cur) => {
return acc.concat(Array.isArray(cur) ? flattened3(cur) : cur);
}, [])
}
// 方法4 => 扩展运算符
// 限制:与方法三一样
function flattened4(arr) {
return [].concat(...arr);
}
// 方法4改进版
function flattened4(arr) {
while(arr.some(item => Array.isArray(item))) {
arr = [].concat(...arr);
}
return arr;
}
// 思考 => 结合数组去重和降维的方法,实现数组的并集操作
function union(...args) {
return [...new Set([].concat(...args))];
}
使用Symbol优化代码
实现一个getArea()方法,返回三角形,圆以及矩形的面积
// 原始
function getArea(shape, options) {
let area = 0;
switch(shape) {
case 'triangle':
area = .5 * options.width * options.height;
break;
case 'circle':
const Pi = 3.14;
area = Pi * options.width * options.height;
break;
case 'rectangle':
area = options.width * options.height;
break;
}
return area;
}
getArea('triangle', {width: 100, height: 100});
getArea('circle', {width:200, heigth: 200})
// 使用symbol
const shapeType = {
triangle: Symbol(),
circle: Symbol(),
rectangle: Symbol()
}
// 省略部分代码
...
switch(case) {
case: shapeType.triangle:
case: shapeType.circle:
case: shapeType.rectangle:
}
getArea(shapeType.triangle, {width: 100, height: 100});
getArea(shapeType.circle, {width: 200, height: 200});