GithubHelp home page GithubHelp logo

sunny-117 / js-challenges Goto Github PK

View Code? Open in Web Editor NEW
1.9K 1.9K 231.0 2.33 MB

✨✨✨ Challenge your JavaScript programming limits step by step

Home Page: https://juejin.cn/column/7244788137410560055

CSS 3.69% JavaScript 74.49% Shell 3.04% HTML 18.79%
html-css-javascript javascript nodejs promise react typescript vuejs

js-challenges's Introduction

js-challenges's People

Contributors

chelestewang avatar cwrv07 avatar dif1202 avatar dossweet avatar failurman avatar hannah-bingo avatar jlx2002 avatar lechang-zhang avatar levyevans-s avatar lhp96 avatar linjunc avatar littlebearhat avatar lxy-jason avatar lzxjack avatar nasuke avatar object-kaz avatar pcjmy avatar qiuye-zhou avatar richard-zhang1019 avatar stream-web avatar sunny-117 avatar veneno-o avatar zhuba-ahhh avatar zzk520 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-challenges's Issues

列表转成树形结构

let arr = [
    { id: 1, name: '部门1', pid: 0 },
    { id: 2, name: '部门2', pid: 1 },
    { id: 3, name: '部门3', pid: 1 },
    { id: 4, name: '部门4', pid: 3 },
    { id: 5, name: '部门5', pid: 4 },
    { id: 6, name: '部门6', pid: 0 },
]
function getTreeList(rootList, id, list) {
    for (const item of rootList) {
        if (item.parent === id) {
            list.push(item);
        }
    }
    for (const i of list) {
        i.children = [];
        getTreeList(rootList, i.id, i.children);
        if (i.children.length === 0) {
            delete i.children;
        }
    }
    return list;
}
const res = getTreeList(rootList, null, []);
console.log("res", res);

树形结构转成列表

const data = [
    {
        id: 1,
        text: '节点1',
        parentId: 0,
        children: [
            {
                id: 2,
                text: '节点1_1',
                parentId: 1
            }
        ]
    }
]
function treeToList(data) {
    let res = [];
    const dfs = (tree) => {
        tree.forEach((item) => {
            if (item.children) {
                dfs(item.children);
                delete item.children;
            }
            res.push(item);
        });
    };
    dfs(data);
    return res;
}

JSON.stringify

function toJSON(data){

}

// test
toJSON(""); // -> ""
toJSON("abc"); // -> "abc"
toJSON(123); // -> 123
toJSON({a:1, b:2}); // -> {"a":1, "b":2}
toJSON(["1", 3, {name:"monica", age:18}]); //-> ["1", 3, {"name":"monica", "age":18}]

6. Promise.resolve

Promise.resolve = function (data) {
    if (data instanceof MyPromise) {
      return data;
    }
    return new MyPromise((resolve, reject) => {
      if (isPromise(data)) {
        data.then(resolve, reject);
      } else {
        resolve(data);
      }
    });
  }

Array.prototype.copy

Array.prototype.copy = function () {
    return [...this, ...this]
}
console.log([1, 2, 3, 4, 5].copy());

正则表达式模版字符串

String.prototype.render = function (data) {
    return this.replace(/{{[.\s\S]*?}}/g, match => {
        if ((match = match.substring(2, match.length - 2).trim()) == "") {
            return "";
        } else if (match.startsWith("#")) {
            return eval(match.substr(1, match.length - 1));
        } else {
            return data[match] ? data[match] : "";
        }
    })
}


const data = {
    name: "小明",
    age: 16,
    school: "第三中学",
    classroom: "教室2"
}


console.log(
    "{{ name }} 今年 {{ age }} 岁,就读于 {{ school }} 今天在 {{ classroom }} 上课,{{ name }} {{ #data.age >= 18 ? '成年了' : '未成年' }}".render(data)
);
// 小明 今年 16 岁,就读于 第三中学 今天在 教室2 上课,小明 未成年

console.log(
    `{{name}}说了句{{#
        if (data.age >= 18) {
            "我已经成年了!"
        } else {
            "我还没有成年!"
        }
    }}`.render(data)
);
// 小明说了句我还没有成年!

Object.is

Object.is = function (x, y) {
  if (x === y) {
    // 当前情况下,只有一种情况是特殊的,即 +0 -0
    // 如果 x !== 0,则返回true
    // 如果 x === 0,则需要判断+0和-0,则可以直接使用 1/+0 === Infinity 和 1/-0 === -Infinity来进行判断
    return x !== 0 || 1 / x === 1 / y;
  }
  // x !== y 的情况下,只需要判断是否为NaN,如果x!==x,则说明x是NaN,同理y也一样
  // x和y同时为NaN时,返回true
  return x !== x && y !== y;
};

JSON2DOM = react的render函数

{
  tag: 'DIV',
  attrs:{
  id:'app'
  },
  children: [
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] },
        { tag: 'A', children: [] }
      ]
    }
  ]
}
把上诉虚拟Dom转化成下方真实Dom
<div id="app">
  <span>
    <a></a>
  </span>
  <span>
    <a></a>
    <a></a>
  </span>
</div>

Array.prototype.getLevel

Array.prototype.getLevel = function () {
    let max = 1
    for (const a of this) {
        if (a instanceof Array) {
            const depth = a.getLevel() + 1
            if (max < depth) max = depth
        }
    }
    return max
};
const a1 = [1, 2, [1], [1, [2, [3]]]];
console.log(a1.getLevel()); //4

DOM2JSON

{
  tag: 'DIV',
  children: [
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] }
      ]
    },
    {
      tag: 'SPAN',
      children: [
        { tag: 'A', children: [] },
        { tag: 'A', children: [] }
      ]
    }
  ]
}

function dom2Json(domtree) {
  let obj = {};
  obj.name = domtree.tagName;
  obj.children = [];
  domtree.childNodes.forEach((child) => obj.children.push(dom2Json(child)));
  return obj;
}

lodash.get

const obj = {
    a: {
        b: 123
    },
    arr: [
        {
            demo: 'demo'
        }
    ]
}
function getKey(obj, str) {
   
}
console.log(getKey(obj, 'a.b'));
console.log(getKey(obj, 'arr[0].demo'));

字符串的大小写取反

let str = "QIANDUANGOngchengshi猕猴桃Jquery很帅!哈哈 haha";
str = str.replace(/[a-zA-Z]/g, (content) => {
  return content.toUpperCase() === content
    ? content.toLowerCase()
    : content.toUpperCase();
});
console.log(str);

7. Promise.reject

 /**
   * 得到一个被拒绝的Promise
   * @param {*} reason
   */
  Promise.reject=function(reason) {
    return new MyPromise((resolve, reject) => {
      reject(reason);
    });
  }

String.prototype.repeat

 String.prototype.repeat= function (n) {
    let str = this;
    let res = ''
    while (n) {
        res += str;
        n--
    }
    return res
}
console.log('abc'.repeat(3));

Object.assign

Object.assign2 = function(target, ...source) {
  let ret = Object(target) 
  source.forEach(function(obj) {
    if (obj) {
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          ret[key] = obj[key]
        }
      }
    }
  })
  return ret
}
const obj1 = {a: 1}
const obj2 = {b: 2}
const res = Object.assign2(obj1, obj2)
console.log(obj1);

Object.create()

Object.create2 = function(proto, propertyObject = undefined) {
    function F() {}
    F.prototype = proto
    const obj = new F()
    if (propertyObject != undefined) {
        Object.defineProperties(obj, propertyObject)
    }
    if (proto === null) {
        // 创建一个没有原型对象的对象,Object.create(null)
        obj.__proto__ = null
    }
    return obj
}

Array.prototype.map

const arr = [1, 2, 3]
Array.prototype.map = function (callback) {
    const res = [];
    for (let i = 0; i < this.length; i++) {
        res.push(callback(this[i], i, this))
    }
    return res;
}
const res = arr.map((ele, index, arr) => {
    return ele * 2
})
console.log(res)

Array.prototype.filter

Array.prototype.myFilter = function (callback) {
  const res = [];
  for (let i = 0; i < this.length; i++) {
    callback(this[i], i, this) && res.push(this[i]);
  }
  return res;
};

实现es6的map集合

class MyMap {
  constructor(iterable = []) {
    //验证是否是可迭代的对象
    if (typeof iterable[Symbol.iterator] !== "function") {
      throw new TypeError(`你提供的${iterable}不是一个可迭代的对象`)
    }
    this._datas = [];
    for (const item of iterable) {
      // item 也得是一个可迭代对象
      if (typeof item[Symbol.iterator] !== "function") {
        throw new TypeError(`你提供的${item}不是一个可迭代的对象`);
      }
      const iterator = item[Symbol.iterator]();
      //不一定是数组,所以用这种方式
      const key = iterator.next().value;
      const value = iterator.next().value;
      this.set(key, value);
    }

  }

  set(key, value) {
    const obj = this._getObj(key);
    if (obj) {//已经有了就是要修改
      //修改
      obj.value = value;
    }
    else {//没有的话添加
      this._datas.push({
        key,
        value
      })
    }
  }

  get(key) {
    const item = this._getObj(key);
    if (item) {
      return item.value;
    }
    return undefined;// 找不到
  }

  get size() {
    return this._datas.length;
  }

  delete(key) {
    for (let i = 0; i < this._datas.length; i++) {
      const element = this._datas[i];
      if (this.isEqual(element.key, key)) {
        this._datas.splice(i, 1);
        return true;
      }
    }
    return false;
  }

  clear() {
    this._datas.length = 0;
  }

  /**
     * 根据key值从内部数组中,找到对应的数组项
     * @param {*} key 
     */
  _getObj(key) {
    for (const item of this._datas) {
      if (this.isEqual(item.key, key)) {
        return item;
      }
    }
  }

  has(key) {
    return this._getObj(key) !== undefined;
  }

  /**
     * 判断两个数据是否相等
     * @param {*} data1 
     * @param {*} data2 
     */
  isEqual(data1, data2) {
    if (data1 === 0 && data2 === 0) {
      return true;
    }
    return Object.is(data1, data2);
  }

  *[Symbol.iterator]() {//迭代器创建函数本身就是生成器函数  *
    for (const item of this._datas) {
      yield [item.key, item.value];
    }
  }

  forEach(callback) {
    for (const item of this._datas) {
      callback(item.value, item.key, this);
    }
  }
}

Array.prototype.fill

Array.prototype.myFill = function (initValue, start = 0, end) {
  end = end < 0 ? this.length + end : end;
  for (let i = start; i < end; i++) {
    this[i] = initValue;
  }
  return this;
};
let arr = [3, 3, 21, 3, 14, 12, 4, 1, 2];
console.log(arr.fill(1, 3, 5));

2. 实现Promise.finally

/**
   * 无论成功还是失败都会执行回调
   * @param {Function} onSettled
   */
 Promise.prototype.finally = function (onSettled) {
    return this.then(
      (data) => {
        onSettled(); // 实现了收不到参数了
        return data;
      },
      (reason) => {
        onSettled();
        throw reason;
      }
    );
    // finally函数 返回结果应该是无效的
  }
  
/******test finally*******/
// 无论什么结果,都会运行
const pro = new Promise((resolve, reject) => {
  resolve(1);
});
const pro2 = pro.finally((d) => {
  console.log("finally", d); // 收不到d参数
  // 本身不改变状态,但是抛出一个错误,数据就会变成它的错误
  // throw 123;
  return 123; //不起作用
});
setTimeout(() => {
  console.log(pro2);
});

8. 完整实现Promise A+

// 记录Promise的三种状态
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

/**
 * 运行一个微队列任务
 * 把传递的函数放到微队列中
 * @param {Function} callback
 */
function runMicroTask(callback) {
  // 判断node环境
  // 为了避免「变量未定义」的错误,这里最好加上前缀globalThis
  // globalThis是一个关键字,指代全局对象,浏览器环境为window,node环境为global
  if (globalThis.process && globalThis.process.nextTick) {
    process.nextTick(callback);
  } else if (globalThis.MutationObserver) {
    const p = document.createElement("p");
    const observer = new MutationObserver(callback);
    observer.observe(p, {
      childList: true, // 观察该元素内部的变化
    });
    p.innerHTML = "1";
  } else {
    setTimeout(callback, 0);
  }
}

/**
 * 判断一个数据是否是Promise对象
 * @param {any} obj
 * @returns
 */
function isPromise(obj) {
  return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}

class MyPromise {
  /**
   * 创建一个Promise
   * @param {Function} executor 任务执行器,立即执行
   */
  constructor(executor) {
    this._state = PENDING; // 状态
    this._value = undefined; // 数据
    this._handlers = []; // 处理函数形成的队列
    try {
      executor(this._resolve.bind(this), this._reject.bind(this));
    } catch (error) {
      this._reject(error);
      console.error(error);
    }
  }

  /**
   * 向处理队列中添加一个函数
   * @param {Function} executor 添加的函数
   * @param {String} state 该函数什么状态下执行
   * @param {Function} resolve 让then函数返回的Promise成功
   * @param {Function} reject 让then函数返回的Promise失败
   */
  _pushHandler(executor, state, resolve, reject) {
    this._handlers.push({
      executor,
      state,
      resolve,
      reject,
    });
  }

  /**
   * 根据实际情况,执行队列
   */
  _runHandlers() {
    if (this._state === PENDING) {
      // 目前任务仍在挂起
      return;
    }
    while (this._handlers[0]) {
      const handler = this._handlers[0];
      this._runOneHandler(handler);
      this._handlers.shift();
    }
  }

  /**
   * 处理一个handler
   * @param {Object} handler
   */
  _runOneHandler({ executor, state, resolve, reject }) {
    runMicroTask(() => {
      if (this._state !== state) {
        // 状态不一致,不处理
        return;
      }

      if (typeof executor !== "function") {
        // 传递后续处理并非一个函数
        this._state === FULFILLED ? resolve(this._value) : reject(this._value);
        return;
      }
      try {
        const result = executor(this._value);
        if (isPromise(result)) {
          result.then(resolve, reject);
        } else {
          resolve(result);
        }
      } catch (error) {
        reject(error);
        console.error(error);
      }
    });
  }

  /**
   * Promise A+规范的then
   * @param {Function} onFulfilled
   * @param {Function} onRejected
   */
  then(onFulfilled, onRejected) {
    return new MyPromise((resolve, reject) => {
      this._pushHandler(onFulfilled, FULFILLED, resolve, reject);
      this._pushHandler(onRejected, REJECTED, resolve, reject);
      this._runHandlers(); // 执行队列
    });
  }

  /**
   * 仅处理失败的场景
   * @param {Function} onRejected
   */
  catch(onRejected) {
    return this.then(null, onRejected);
  }

  /**
   * 无论成功还是失败都会执行回调
   * @param {Function} onSettled
   */
  finally(onSettled) {
    return this.then(
      (data) => {
        onSettled();
        return data;
      },
      (reason) => {
        onSettled();
        throw reason;
      }
    );
  }

  /**
   * 更改任务状态
   * @param {String} newState 新状态
   * @param {any} value 相关数据
   */
  _changeState(newState, value) {
    if (this._state !== PENDING) {
      // 目前状态已经更改
      return;
    }
    this._state = newState;
    this._value = value;
    this._runHandlers(); // 状态变化,执行队列
  }

  /**
   * 标记当前任务完成
   * @param {any} data 任务完成的相关数据
   */
  _resolve(data) {
    this._changeState(FULFILLED, data);
  }

  /**
   * 标记当前任务失败
   * @param {any} reason 任务失败的相关数据
   */
  _reject(reason) {
    this._changeState(REJECTED, reason);
  }

}

对象树遍历

const tree = {
    name: 'root',
    children: [
        {
            name: 'c1',
            children: [
                {
                    name: 'c11',
                    children: []
                },
                {
                    name: 'c12',
                    children: []
                }
            ]
        },
        {
            name: 'c2',
            children: [
                {
                    name: 'c21',
                    children: []
                },
                {
                    name: 'c22',
                    children: []
                }
            ]
        }
    ]
}

// 深度优先的方式遍历 打印 name
// ['root', 'c1','c11', 'c12', 'c2', 'c21', 'c22']
// 我写的
function solve(root) {
    const res = []
    function dfs(root) {
        for (const key in root) {
            if (key === 'name') {
                res.push(root[key])
            } else if (key === 'children') {
                root[key].forEach(ele => {
                    dfs(ele)
                });
            }
        }
    }
    dfs(root)
    return res;
}
console.log(solve(tree));

查找json中的children路径

现有如下json(简化为对象),已知每个节点id唯一,编写findNode(id),返回路径,如findNode(5 输出 1->4->5

json = {
    id: 1,
    children: [
        { id: 2, children: [{ id: 3, children: [] }] },
        {
            id: 4,
            children: [
                { id: 5, children: [] },
                { id: 6, children: [] },
            ],
        },
        { id: 7, children: [] },
    ],
};
function findNode(obj) {
    const res = []
    function dfs(obj, currPath, target) {
        if (!obj) return;
        if (obj.id === target) {
            currPath += obj.id
            res.push(currPath)
            return
        }
        currPath += obj.id + '->'
        obj.children && obj.children.forEach(ele => {
            dfs(ele, currPath, target)
        });
    }
    dfs(obj, '', 5)
    return res;
}

Array.prototype.forEach

// 无返回值,调用callback
Array.prototype.myForEach = function (callback) {
  if (typeof callback !== "function") {
    throw new TypeError(callback + " is not a function");
  }
  for (let i = 0; i < this.length; i++) {
    callback(this[i], i, this);
  }
};

获取树结构中的name:getName

let data = [
      {
          "name": "1-1",
          "kind": "oo",
          "children": [
              {
                  "name": "2-2",
                  "kind": "ii",

              },
              {
                  "name": "3-3",
                  "children": [
                      {
                          "name": "4-4",
                          "children": [
                              {
                                  "name": '707'
                              }
                          ]
                      }
                  ]
              }
          ]
      },
      {
          "name": "5-5",
      },
      {
          "name": "6-6"
      }
  ]
  function getName(data, key = "name") {
      let result = [];
      if (Array.isArray(data)) {
          for (let item of data) {
              if (item[key]) {
                  result.push(item[key]);
              }
              if (item.children) {
                  result = result.concat(getName(item.children));
              }
          }
          return result;
      } else {
          return result;
      }
  }

  console.log(getName(data))

计算目录树的深度

const tree = {
    name: 'root',
    children: [
        { name: '叶子1-1' },
        { name: '叶子1-2' },
        {
            name: '叶子2-1',
            children: [{
                name: '叶子3-1',
                children: [{
                    name: '叶子4-1',
                    children: [{}]
                }]
            }]
        }
    ]
}

function getLevel(tree) {
    if (tree == null) return 0;
    const queue = [tree]
    let dep = 0;
    while (queue.length) {
        dep++;
        const size = queue.length
        for (let i = 0; i < size; i++) {
            const node = queue.shift()
            if (node.children) {
                for (const child of node.children) {
                    queue.push(child)
                }
            }
        }
    }
    return dep
}
console.log(getLevel(tree));

4. 实现Primise.race

/**
   * 返回的Promise与第一个有结果的一致
   * @param {iterator} proms
   */
  Promise.race=function(proms) {
    return new MyPromise((resolve, reject) => {
      for (const p of proms) {
        MyPromise.resolve(p).then(resolve, reject);
      }
    });
  }

instanceof

function myInstanceof(left, right) {
  let proto = Object.getPrototypeOf(left), // 获取对象的原型
      prototype = right.prototype; // 获取构造函数的 prototype 对象

  // 判断构造函数的 prototype 对象是否在对象的原型链上
  while (true) {
    if (!proto) return false;
    if (proto === prototype) return true;
    proto = Object.getPrototypeOf(proto);
  }
}
function Person() { };
var p = new Person();
console.log(myInstanceof(p, Object));
// console.log(p instanceof Person);//true

Array.prototype.unshift

Array.prototype.myUnshift = function (...items) {
    this.reverse().push(...items.reverse())
    this.reverse()
    return this.length
}

正则判断手机号,qq,颜色,邮箱

// 手机号
let reg1 = /^1[44578]\d{9}$/g;
let str1 = '15928229999'
console.log(reg1.test(str1));
// qq号
let reg2 = /^[1-9][0-9]{4,9}$/g;
let str2 = '159222'
console.log(reg2.test(str2));

// 颜色
let reg3 = /#?([0-9a-fA-F]{6}|[0-9a-fA-F]{3})/g;
let str3 = '#abc'
console.log(reg3.test(str3));
// 邮箱
let reg4 = /^([A-za-z0-9_\-\.]+)+@([A-za-z0-9_\-\.]+)\.([A-Za-z]{2, 6})$/g;//+一到多
var reg = /^([a-zA-Z]|[0-9])(\w|\-)+@[a-zA-Z0-9]+\.([a-zA-Z]{2,4})$/;
let str4 = '[email protected]'
console.log(reg4.test(str4));

JSON.parse

// eval 实现
var json = '{"a":"1", "b":2}';
var obj = eval("(" + json + ")");  // obj 就是 json 反序列化之后得到的对象
// New Function
var json = '{"name":"小姐姐", "age":20}';
var obj = (new Function('return ' + json))();

实现es6的set集合

class MySet {
  constructor(iterator = []) {//不传默认空数组
    if (typeof iterator[Symbol.iterator] !== "function") {
      throw new TypeError(`你提供的${iterator}不是一个可迭代的对象`)
    }
    this._datas = [];
    for (const item of iterator) {
      this.add(item);
    }
  }

  get size() {
    return this._datas.length;
  }

  add(data) {
    if (!this.has(data)) {// 不包含data,才加入
      this._datas.push(data);
    }
  }

  has(data) {// 是否有data
    for (const item of this._datas) {
      if (this.isEqual(data, item)) {// isEqual判断两个数据是否相等
        return true;
      }
    }
    return false;
  }
  delete(data) {
    for (let i = 0; i < this._datas.length; i++) {
      const element = this._datas[i];
      if (this.isEqual(element, data)) {
        //删除
        this._datas.splice(i, 1);
        return true;
      }
    }
    return false;
  }

  clear() {
    this._datas.length = 0;
  }
  *[Symbol.iterator]() {// 遍历效果
    for (const item of this._datas) {
      yield item;
    }
  }
  forEach(callback) {
    for (const item of this._datas) {
      callback(item, item, this);
    }
  }
  /**
     * 判断两个数据是否相等
     * @param {*} data1 
     * @param {*} data2 
     */
  isEqual(data1, data2) {
    if (data1 === 0 && data2 === 0) {
      return true;
    }
    return Object.is(data1, data2);
  }
}

String.prototype.zpadStart

String.prototype.zpadStart = function (targetLength, padString) {
    let string = this
    while (string.length < targetLength) {
        string = padString + string
    }
    return string
}
const res = 'abc'.padStart(8, "0");

Array.prototype.includes

Array.prototype.myIncludes = function (value, start = 0) {
  start = start < 0 ? this.length + start : start;
  for (let i = start; i < this.length; i++) {
    if (this[i] == value || (Number.isNaN(value) && Number.isNaN(this[i])))
      return true;
  }
  return false;
};

Array.prototype.flat

const arr = [1, [2, 3, [4, 5]], 1, 2, [6, 7]]
Array.prototype.flat = function (deep = 1) {
    let res = []
    deep--
    for (const p of this) {
        if (Array.isArray(p) && deep >= 0) {
            res = res.concat(p.flat(deep))
        } else {
            res.push(p)
        }
    }
    return res
}
console.log(arr.flat(1))

判断有无符合路径和 -> 打印所有路径

const data3 = [
    {
        id: 1,
        name: '前端',
        children: [
            {
                id: 2,
                name: 'html',
                children: [
                    { id: 5, name: 'vue', children: [] },
                    { id: 6, name: 're', children: [] },
                ]
            },
            {
                id: 3,
                name: 'html',
                children: [
                    { id: 7, name: 'vue', children: [] },
                    { id: 8, name: 're', children: [] },
                ]
            }
        ]
    }
]

5. 实现 Promise.prototype.catch

 /**
   * 本质就是then,只是少传了一个onFulfilled
   * 所以仅处理失败的场景
   * @param {*} onRejected
   */
Promise.prototype.catch = function(onRejected) {
    return this.then(null, onRejected);
}

Array.prototype.reduce

Array.prototype.myReduce = function (callback, ...args) {
  let start = 0,
    pre;
  if (args.length) {
    //有参数的话pre等于参数第0项
    pre = args[0];
  } else {
    //没参数的话,默认从数组0项开始
    pre = this[0];
    start = 1;
  }
  for (let i = start; i < this.length; i++) {
    pre = callback(pre, this[i], i, this);
  }
  return pre;
};

trim·

正则写就可以

return str.replace(/(^\s+)|(\s+$)/g,'')//将前空格和后空格替换为空

3. 实现Promise.allSettled

/**
   * 等待所有的Promise有结果后
   * 该方法返回的Promise完成
   * 并且按照顺序将所有结果汇总
   * @param {Iterable} proms
   */
  Promise.allSettled=function(proms) {
    const ps = [];
    for (const p of proms) {
      ps.push(
        MyPromise.resolve(p).then(
          (value) => ({
            status: FULFILLED,
            value,
          }),
          (reason) => ({
            status: REJECTED,
            reason,
          })
        )
      );
    }
    return MyPromise.all(ps);
  }

获取树对象属性

var tree = {
    name: '**',
    children: [
        {
            name: '北京',
            children: [
                {
                    name: '朝阳群众'
                },
                {
                    name: '海淀区'
                },
                {
                    name: '昌平区'
                }
            ]
        },
        {
            name: '浙江省',
            children: [
                {
                    name: '杭州市',
                    code: '0571',
                },
                {
                    name: '嘉兴市'
                },
                {
                    name: '绍兴市'
                },
                {
                    name: '宁波市'
                }
            ]
        }
    ]
};


function fn(tree, name) {
    //bfs
    let Queue = [[tree.name, tree.children]];
    while (Queue.length > 0) {
        //出队当前节点
        let cur = Queue.shift();
        if (cur[0] === name) return { name: name, code: cur[1] }
        //将children入队
        if (cur.length === 1) continue;

        for (let node of cur[1]) {
            let obj = [node.name];
            if (node.hasOwnProperty("children")) obj.push(node.children);
            if (node.hasOwnProperty("code")) obj.push(node.code);
            Queue.push(obj);
        }
    }
    return -1;
}
var node = fn(tree, '杭州市');
console.log(node);    // { name: '杭州市', code: 0571 }

树形结构获取路径名

const treeData = [
    {
        name: "root",
        children: [
            { name: "src", children: [{ name: "index.html" }] },
            { name: "public", children: [] },
        ],
    },
];
const RecursiveTree = (data) => {
    const res = []
    const dfs = (data) => {
        data.forEach(ele => {
            res.push(ele.name)
            ele.children && dfs(ele.children)
        });
    }
    dfs(data)
    return res;
}
console.log(RecursiveTree(treeData));

call apply bind

Function.prototype.call2 = function(context, ...args) {
  context = (context === undefined || context === null) ? window : context
  context.__fn = this
  let result = context.__fn(...args)
  delete context.__fn
  return result
}
Function.prototype.apply2 = function(context, args) {
  context = (context === undefined || context === null) ? window : context
  context.__fn = this
  let result = context.__fn(...args)
  delete context.__fn
  return result
}
Function.prototype.bind2 = function(context, ...args1) {
  context = (context === undefined || context === null) ? window : context
  let _this = this
  return function(...args2) {
    context.__fn = _this
    let result = context.__fn(...[...args1, ...args2])
    delete context.__fn
    return result
  }
}

promisify

手动实现一个promisify函数的意思是:我们把一个异步请求的函数,封装成一个可以具有 then方法的函数,并且在then方法中返回异步方法执行结果的这么一个函数

  1. 具有 then 方法
  2. then 方法里返回异步接口执行结果
// 首先定一个需要进行 promisify 的函数
function asyncFn(a, b, callback) {
        // 异步操作,使用 setTimeout 模拟
        console.log('异步请求参数', a, b)
        setTimeout(function() {
                callback('异步请求结果')
        }, 3000)
}

// 我们希望调用的方式是
const proxy = promisify(asyncFn)
proxy(11,22).then(res => {
        // 此处输出异步函数执行结果
        console.log(res)
})

// 定义一个方法, 需要针对异步方法做封装,所以需要一个入参,既需要promisify的原异步方法
function promisify(func) {
  return function(...args) {
    return new Promise((resolve, reject) => {
      const callback = (err, data) => {
        if (err) {
          reject(err);
        } else {
          resolve(data)
        }
      };
      func.call(this, ...args, callback);
    });
  }
}

Array.prototype.push

Array.prototype.myPush = function (...arg) {
  for (let i = 0; i < arg.length; i++) {
    this[this.length] = arg[i];
  }        
  return this.length;
};

实现new

(1)首先创建了一个新的空对象
(2)设置原型,将对象的原型设置为函数的 prototype 对象。
(3)让函数的 this 指向这个对象,执行构造函数的代码(为这个新对象添加属性)
(4)判断函数的返回值类型,如果是值类型,返回创建的对象。如果是引用类型,就返回这个引用类型的对象。

function myNew(constructorFn, ...args) {
    let newObj = {}
    newObj.__proto__ = constructorFn.prototype;
    // newObj = Object.create(constructor.prototype);
    let result = constructorFn.apply(newObj, args)
    return result instanceof Object ? result : newObj
}
function Animal(name) {
    this.name = name;
}
let animal = myNew(Animal, 'dog')
console.log(animal);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.