黑马程序员技术交流社区

标题: 面试高频JS考查点手写实现(下) [打印本页]

作者: 逆风TO    时间: 2020-3-18 14:59
标题: 面试高频JS考查点手写实现(下)
考查跨域JSONP
[JavaScript] 纯文本查看 复制代码
function fn({ip}) {  console.log(ip); // 
}
function jsonp(cb, domain) {
  const script = document.createElement('script');
  script.src = `https://api.asilu.com/ip/?callback=${cb}&ip=${domain}`;
  document.querySelector('head').appendChild(script);
}

// 获取百度IP
jsonp('fn', 'www.baidu.com');

考查 ES6数组去重
[JavaScript] 纯文本查看 复制代码
function deleteDuplicate(arr) {
  const map = new Map();
  arr.forEach( value => map.set(value, value) );
  return Array.from( map.values() ); // return [ ...map.values() ];
}

const arr = [NaN, 1, [1], [1], 1, '1', 4, 1, 2, 4, 5, 5, NaN, NaN, null, null, undefined, undefined];
deleteDuplicate( arr );
// [NaN, 1, Array(1), Array(1), "1", 4, 2, 5, null, undefined]
// Map 的遍历顺序就是插入顺序

[JavaScript] 纯文本查看 复制代码
function deleteDuplicate(arr) {
  const set = new Set( arr );
  return Array.from( set ); // return [ ...set ];
}
deleteDuplicate( arr );
//[NaN, 1, Array(1), Array(1), "1", 4, 2, 5, null, undefined]


Promise.all
[JavaScript] 纯文本查看 复制代码
Promise._all = function (promises) {
  return new Promise(function(resolve, reject) {
    if (!Array.isArray(promises)) {
      return reject(new TypeError('arguments must be an array'));
    }
    const len = promises.length;
    let cnt = 0;
    let res = [];
    for(let i = 0; i < len; i++) {
      Promise
        .resolve(promises)
        .then(function(value) {
          cnt++;
          res = value;
          if (cnt === len) {
            return resolve(res);
          }
        }, function(reason) {
          return reject(reason);
        });
    }
  });
};

Promise._all([1,2,3,4]);
// Promise {<resolved>: Array(4)}
Promise._all([1,2,3,4]).then(res => console.log(res));
// [1, 2, 3, 4]
Promise._all([1,2,3,Promise.reject('error')]);
// Promise {<rejected>: "error"}
Promise._all([1,2,3,Promise.reject('error')]).catch(reason => console.log(reason));
// error

考查设计模式订阅发布模式
mitt:极简事件监听
[JavaScript] 纯文本查看 复制代码
function mitt(all/*: EventHandlerMap*/) {
  all = all || Object.create(null);

  return {
    on(type/*: string*/, handler/*: EventHandler*/) {
      (all[type] || (all[type] = [])).push(handler);
    },
    off(type/*: string*/, handler/*: EventHandler*/) {
      if (all[type]) {
        all[type].splice(all[type].indexOf(handler) >>> 0, 1);
      }
    },
    emit(type/*: string*/, evt/*: any*/) { // * 表示订阅所有事件消息
      (all[type] || []).slice().map((handler) => { handler(evt); });
      (all['*'] || []).slice().map((handler) => { handler(type, evt); });
    }
  };
}

const m = mitt();
m.on('hello', (name) => console.log('hello ' + name));
m.emit('hello', 'world');

考查算法深拷贝
Vuex版
[JavaScript] 纯文本查看 复制代码
/**
* Get the first item that pass the test
* by second argument function
*
* @param {Array} list
* @param {Function} f
* @return {*}
*/
export function find (list, f) {
  return list.filter(f)[0]
}

/**
* Deep copy the given object considering circular structure.
* This function caches all nested objects and its copies.
* If it detects circular structure, use cached copy to avoid infinite loop.
*
* @param {*} obj
* @param {Array<Object>} cache
* @return {*}
*/
export function deepCopy (obj, cache = []) {
  // just return if obj is immutable value
  if (obj === null || typeof obj !== 'object') {
    return obj
  }

  // if obj is hit, it is in circular structure
  const hit = find(cache, c => c.original === obj)
  if (hit) {
    return hit.copy
  }

  const copy = Array.isArray(obj) ? [] : {}
  // put the copy into cache at first
  // because we want to refer it in recursive deepCopy
  cache.push({
    original: obj,
    copy
  })

  Object.keys(obj).forEach(key => {
    copy[key] = deepCopy(obj[key], cache)
  })

  return copy
}

DFS 全排列
[JavaScript] 纯文本查看 复制代码
输入 `abc`
输出
  abc
  acb
  bac
  bca
  cab
  cba

[JavaScript] 纯文本查看 复制代码
const str = 'abc';
const len = str.length;
const flag = [];
const res = [];

DFS(0);

// cur 表示第 cur 位取得字符
// 每一位有 len 种取法
function DFS(cur) {
  if(cur === len)
    return console.log(res.join(''));

  for(let i = 0; i < len; i++) {
    if(!flag) {
      res[cur] = str;
      flag = true;
      DFS(cur + 1);
      flag = false;
    }
  }
}

快排
[JavaScript] 纯文本查看 复制代码
function swap(arr, i, j) {
  if(i === j) return;
  let tmp = arr;
  arr = arr[j];
  arr[j] = tmp;
}

function quicksort(arr, s, e) {
  if( s >= e ) return;
  const r = s + Math.floor( (e - s) / 2 );

  // 选取中间位r(也可以随机)放在首位
  swap(arr, s, r);

  // 找选取的数应该在数组中的位置
  // 小于则表示位置挪后一位
  let m = s, j = s + 1;
  for(; m < e && j < e; j++) {
    if(arr[j] < arr) {
      swap(arr, ++m, j);
    }
  }
  // 找到 r 的序位
  swap(arr, s, m);

  // 递归排序左左右两边
  quicksort(arr, s, m);
  quicksort(arr, m + 1, e);
}

let arr = [2, 7, 3, 4, 1, 8, 6];
quicksort(arr, 0, arr.length);

考查正则、replace 技巧数钱格式化
[JavaScript] 纯文本查看 复制代码
'99999999'.replace(/\d{1,3}(?=(\d{3})+$)/g, '$&,');

// antd 的例子
'99999999'.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

// 非正则版
function money(str) {
  const len = str.length;
  let start = len % 3 || 3;
  let arr = [str.slice(0, start)];
  while(start < len) {
    arr.push( str.slice(start, start + 3) );
    start += 3;
  }
  return arr.join(',')
}

首尾去空格
[JavaScript] 纯文本查看 复制代码
'   12 34 5 6   '.replace(/^\s+|\s+$/g, '');

相邻字符去重
[JavaScript] 纯文本查看 复制代码
'aaabbbcdfgghhjjkkk'.replace(/([A-Za-z]{1})(\1)+/g, '$1');

单词首字母大写
[JavaScript] 纯文本查看 复制代码
' hi man good  luck '.replace(/\w+/g, function(word) {     return word.substr(0,1).toUpperCase() + word.substr(1);
});


转自:https://juejin.im/post/5e71b2dbf265da5757049549





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2