基础回顾(二)

Author Avatar
Silas Shen 3月 28, 2019

接下来的时间,我会总结几篇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});