9道JavaScript字符串類面試題

本文來源於筆者的開源項目前端面試與進階指南前端

2019-09-12-12-57-09

點擊關注本公衆號獲取文檔最新更新,並能夠領取配套於本指南的 《前端面試手冊》 以及最標準的簡歷模板.git

解析 URL Params 爲對象

let url = 'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled';
parseParam(url)
/* 結果
{ user: 'anonymous',
  id: [ 123, 456 ], // 重複出現的 key 要組裝成數組,能被轉成數字的就轉成數字類型
  city: '北京', // 中文需解碼
  enabled: true, // 未指定值得 key 約定爲 true
}
*/
function parseParam(url) {
  const paramsStr = /.+\?(.+)$/.exec(url)[1]; // 將 ? 後面的字符串取出來
  const paramsArr = paramsStr.split('&'); // 將字符串以 & 分割後存到數組中
  let paramsObj = {};
  // 將 params 存到對象中
  paramsArr.forEach(param => {
    if (/=/.test(param)) { // 處理有 value 的參數
      let [key, val] = param.split('='); // 分割 key 和 value
      val = decodeURIComponent(val); // 解碼
      val = /^\d+$/.test(val) ? parseFloat(val) : val; // 判斷是否轉爲數字

      if (paramsObj.hasOwnProperty(key)) { // 若是對象有 key,則添加一個值
        paramsObj[key] = [].concat(paramsObj[key], val);
      } else { // 若是對象沒有這個 key,建立 key 並設置值
        paramsObj[key] = val;
      }
    } else { // 處理沒有 value 的參數
      paramsObj[param] = true;
    }
  })

  return paramsObj;
}

模板引擎實現

let template = '我是{{name}},年齡{{age}},性別{{sex}}';
let data = {
  name: '姓名',
  age: 18
}
render(template, data); // 我是姓名,年齡18,性別undefined
function render(template, data) {
  const reg = /\{\{(\w+)\}\}/; // 模板字符串正則
  if (reg.test(template)) { // 判斷模板裏是否有模板字符串
    const name = reg.exec(template)[1]; // 查找當前模板裏第一個模板字符串的字段
    template = template.replace(reg, data[name]); // 將第一個模板字符串渲染
    return render(template, data); // 遞歸的渲染並返回渲染後的結構
  }
  return template; // 若是模板沒有模板字符串直接返回
}

轉化爲駝峯命名

var s1 = "get-element-by-id"

// 轉化爲 getElementById
var f = function(s) {
    return s.replace(/-\w/g, function(x) {
        return x.slice(1).toUpperCase();
    })
}

查找字符串中出現最多的字符和個數

例: abbcccddddd -> 字符最多的是d,出現了5次程序員

let str = "abcabcabcbbccccc";
let num = 0;
let char = '';

 // 使其按照必定的次序排列
str = str.split('').sort().join('');
// "aaabbbbbcccccccc"

// 定義正則表達式
let re = /(\w)\1+/g;
str.replace(re,($0,$1) => {
    if(num < $0.length){
        num = $0.length;
        char = $1;        
    }
});
console.log(`字符最多的是${char},出現了${num}次`);

字符串查找

請使用最基本的遍從來實現判斷字符串 a 是否被包含在字符串 b 中,並返回第一次出現的位置(找不到返回 -1)。github

a='34';b='1234567'; // 返回 2
a='35';b='1234567'; // 返回 -1
a='355';b='12354355'; // 返回 5
isContain(a,b);
function isContain(a, b) {
  for (let i in b) {
    if (a[0] === b[i]) {
      let tmp = true;
      for (let j in a) {
        if (a[j] !== b[~~i + ~~j]) {
          tmp = false;
        }
      }
      if (tmp) {
        return i;
      }
    }
  }
  return -1;
}

實現千位分隔符

// 保留三位小數
parseToMoney(1234.56); // return '1,234.56'
parseToMoney(123456789); // return '123,456,789'
parseToMoney(1087654.321); // return '1,087,654.321'
function parseToMoney(num) {
  num = parseFloat(num.toFixed(3));
  let [integer, decimal] = String.prototype.split.call(num, '.');
  integer = integer.replace(/\d(?=(\d{3})+$)/g, '$&,');
  return integer + '.' + (decimal ? decimal : '');
}

正則表達式(運用了正則的前向聲明和反前向聲明):面試

function parseToMoney(str){
    // 僅僅對位置進行匹配
    let re = /(?=(?!\b)(\d{3})+$)/g; 
   return str.replace(re,','); 
}

判斷是不是電話號碼

function isPhone(tel) {
    var regx = /^1[34578]\d{9}$/;
    return regx.test(tel);
}

驗證是不是郵箱

function isEmail(email) {
    var regx = /^([a-zA-Z0-9_\-])+@([a-zA-Z0-9_\-])+(\.[a-zA-Z0-9_\-])+$/;
    return regx.test(email);
}

驗證是不是身份證

function isCardNo(number) {
    var regx = /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/;
    return regx.test(number);
}

參考:正則表達式


公衆號

想要實時關注筆者最新的文章和最新的文檔更新請關注公衆號程序員面試官,後續的文章會優先在公衆號更新.算法

簡歷模板: 關注公衆號回覆「模板」獲取數組

《前端面試手冊》: 配套於本指南的突擊手冊,關注公衆號回覆「fed」獲取dom

2019-08-12-03-18-41

相關文章
相關標籤/搜索