mtonhuang/blog

复习

mtonhuang opened this issue · 0 comments

<script>
      /* shopee前端 */

      /*
      写一个class 对 主站搜索的关键词队列进行记忆和排序 队列最大维护n个关键词
      比如用户依次输入 维护5个
      a b c d e d e a
      结果需要为
      a e d c b (最近搜索的排前)
      */

      class Point {
        constructor(val, n) {
          this.val = val;
          this.n = n;
        }
        toSort() {
          const map = new Map();
          this.val
            .split('')
            .reverse()
            .forEach((item, index) => {
              map.set(item);
            });
          return [...map.keys()].splice(0, this.n).join('');
        }
      }
      var p = new Point('abcdedea', 5);
      // 'aedcb'
      console.log(p.toSort());
      console.log(Point === Point.prototype.constructor);
      console.log(p.constructor === Point.prototype.constructor);
      console.log(p.__proto__ === Point.prototype);

      // ==================================================

      const arr = [1, 4, 9];
      const newArr = arr.map(
        (x) => {
          console.log(x + this.a);
          return x + this.a;
        },
        { a: 1 }
      );
      console.log(newArr);

      // ===================================================

      window.name = 'linklogis';
      function A() {
        this.name = 123;
      }
      A.prototype.getA = function () {
        return this.name + 1;
      };
      let a = new A();
      let funcA = a.getA;
      funcA();
      console.log(funcA());

      // ===================================================
      // es6的扩展运算符 ... 相当于 Object.assign -> 第一层深拷贝,第二层以后浅拷贝。
      // let aClone = { ...a }; 等同于 let aClone = Object.assign({}, a);
      let obj1 = { a: 1, b: { c: 2 } };
      let obj2 = { ...obj1 };
      obj1.a = 3;
      console.log(obj1); // {a:3,b:{c:2}}
      console.log(obj2); // {a:1,b:{c:2}}
      obj2.a = 4;
      console.log(obj1); // {a:1,b:{c:2}}
      console.log(obj2); // {a:4,b:{c:2}}
      obj2.b.c = 5;
      console.log(obj1); // {a:1,b:{c:5}}
      console.log(obj2); // {a:1,b:{c:5}

      // ===================================================

      new Promise((resolve, reject) => {
        resolve('success');
      })
        .then(() => {
          throw Error('oh');
        })
        .catch((error) => {
          return 'yes';
        })
        .catch((error) => console.log(error.message))
        .then((error) => console.log(error.message));

      // ===================================================

      var p1 = new Promise(function (res, rej) {
        console.log('promise 1');
        res();
      });
      setTimeout(function () {
        console.log('setTime0');
      });
      var p2 = new Promise(function (res, rej) {
        setTimeout(() => {
          res(1);
        }, 0);
      });
      setTimeout(function () {
        console.log('setTime1');
      });
      for (let i = 0; i < 3; i++) {
        p2.then(function (val) {
          console.log('promise then -' + i);
        });
      }
      Promise.resolve().then(() => {
        console.log('promise then');
      });
      p1.then(function () {
        console.log('promise 1 resolved');
      });
      console.log('finished');

      // ===================================================

      const input = [
        { province: '广东', city: '深圳', area: '宝安' },
        { province: '广东', city: '深圳', area: '南山' },
        { province: '广东', city: '汕头', area: '潮阳' },
        { province: '广东', city: '广州', area: '天河' },
        { province: '浙江', city: '杭州', area: '西湖' },
      ];
      function updateList() {
        let output = [];
        input.forEach((item) => {
          let provinceIdx = output.findIndex((sitem) => sitem.value === item.province);
          if (provinceIdx === -1) {
            output.push({
              value: item.province,
              children: [
                {
                  value: item.city,
                  children: [
                    {
                      value: item.area,
                    },
                  ],
                },
              ],
            });
          } else {
            let cityIdx = output[provinceIdx].children.findIndex(
              (csitem) => csitem.value === item.city
            );
            if (cityIdx === -1) {
              output[provinceIdx].children.push({
                value: item.city,
                children: [{ value: item.area }],
              });
            } else {
              output[provinceIdx].children[cityIdx].children.push({
                value: item.area,
              });
            }
          }
        });
        return output;
      }

      console.log(updateList(input), 2131231);

      // const output = [
      //   {
      //     value: '广东',
      //     children: [
      //       {
      //         value: '深圳',
      //         children: [{ value: '宝安' }, { value: '南山' }],
      //       },
      //       {
      //         value: '汕头',
      //         children: [{ value: '潮阳' }],
      //       },
      //     ],
      //   },
      //   {
      //     value: '浙江',
      //     children: [
      //       {
      //         value: '杭州',
      //         children: '西湖',
      //       },
      //     ],
      //   },
      // ];

      // ===================================================

      // 求一个数平方根,保留三位小数

      function funSqrt(x) {
        let left = 1,
          right = x;
        while (left <= right) {
          let mid = left + ((right - left) >> 1);
          if (mid <= x / mid) {
            if (mid + 1 > x / (mid + 1)) {
              return mid;
            }
            left = mid + 1;
          } else {
            right = mid - 1;
          }
        }
        return 0;
      }

      /* 富途前端 */

      // 实现Promise.all 有一个失败就输出,否则全部

      let promise1 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('1');
        }, 1000);
      });
      let promise2 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('2');
        }, 3000);
      });
      let promise3 = new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve('3');
        }, 1000);
      });
      // console.log(promise1);
      // console.log(promise2);
      // console.log(promise3);
      // Promise.all([promise1, promise2, promise3])
      //   .then((res) => {
      //     console.log(res);
      //   })
      //   .catch((err) => console.log(err));

      Promise.testAll = function (promiseArr) {
        return new promise((resolve, reject) => {
          let arr = [],
            num = 0;
          promiseArr.forEach((item, index) => {
            Promise.resolve(item)
              .then((res) => {
                arr[index] = res;
                num += 1;
                if (num === promiseArr.length) resolve(arr);
              })
              .catch((error) => {
                reject(error);
              });
          });
        });
      };

      // 实现Promise.race 输出最快promise
      Promise.testRace = function (promiseArr) {
        return new promise((resolve, reject) => {
          promiseArr.forEach((item) => {
            Promise.resolve(item)
              .then((res) => {
                resolve(res);
              })
              .catch(() => {
                reject();
              });
          });
        });
      };

      // 实现Promise.any 全部失败输出,否则任意一个
      Promise.any = function (promiseArr) {
        return new promise((resolve, reject) => {
          let arr = [],
            num = 0;
          promiseArr.forEach((item, index) => {
            Promise.resolve(item)
              .then()
              .catch((err) => {
                arr[index] = { status: 'reject', val: err };
                num += 1;
                if (num === promiseArr.length) reject(new Error('没有promise成功'));
              });
          });
        });
      };

      // 爬楼梯 记忆化递归
      /* 1.先对n为0这种特殊情况进行处理,然后n为1和2时直接return即可
         2.memo数组:存储中间结果,避免重复计算
         3.接下来就是判断memo[n]是否存在,如果计算过即存在,直接返回,无需重复计算;若不存在,则进行递归计算,为前两个之和。
      */
      const memo = new Map();
      var climbStairs = function (n) {
        const memo = [];
        if (n === 0) return 1;
        if (n <= 3) return n;
        if (memo[n]) {
          return memo[n];
        } else {
          memo[n] = climbStairs(n - 1) + climbStairs(n - 2);
        }
        return memo[n];
        /* 或者 map实现
        if (n === 0) return 1;
        if (n <= 3) return n;
        if (memo.get(n)) {
          return memo.get(n);
        } else {
          memo.set(n, climbStairs(n - 1) + climbStairs(n - 2));
        }
        return memo.get(n);
      */
      };

      console.log(climbStairs(6));

      // 爬楼梯 常规
      var climbStairs1 = function (n) {
        const memo = [];
        memo[0] = 1;
        memo[1] = 1;
        for (let i = 2; i <= n; i++) {
          memo[n] = memo[n - 1] + memo[n - 2];
        }
        return memo[n];
      };

      /*  22. 括号生成
      数字 n 代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且 有效的 括号组合。
      示例 1:
      输入:n = 3
      输出:["((()))","(()())","(())()","()(())","()()()"]
      示例 2:
      输入:n = 1
      输出:["()"]
      */

      var generateParenthesis = function (n) {
        let set = new Set(['()']);
        for (let i = 2; i <= n; i++) {
          let setChild = new Set();
          for (let item of set) {
            for (let j = 0; j < item.length; j++) {
              setChild.add(item.slice(0, j) + '()' + item.slice(j));
            }
          }
          set = setChild;
        }
        return [...set];
      };

      /*前端基础*/

      // 原型链
      // prototype => 原型对象 ;constructor => 我们称为构造函数,因为它指回构造函数本身
      // 对象原型(proto) 和构造函数( prototype )原型对象里面都有一个属性 constructor属性
      let Fun = function () {}; // => 构造函数
      let fun = new Fun(); // => 实例对象

      // 构造函数 <-> 原型对象 实例对象 <-> 实例对象
      Fun.prototype == fun.__proto__;
      Fun.prototype.constructor === Fun;
      fun.__proto__.constructor === Fun;

      // 实现call
      Function.prototype.callTest = function (context) {
        context = context || window;
        context.fn = this;
        let args = [];
        for (let i = 0; i < arguments.length; i++) {
          args.push('arguments[' + i + ']');
        }
        // var result = context.fn(...args);
        var result = eval('context.fn(' + args + ')'); // eval里的args会自动执行array.toString()
        delete context.fn;
        return result;
      };

      // 实现深拷贝
      function deepClone(obj, hash = new WeakMap()) {
        // 用hash值记录防止循环引用
        if (hash.has(ojb)) {
          return obj;
        }
        let res = null;
        const reference = [Date, Set, RegExp, WeakSet, Map, WeakMap, Error];
        if (reference.includes(obj?.constructor)) {
          res = new obj.constructor(obj);
        } else if (Array.isArray(obj)) {
          res = [];
          obj.forEach((item, index) => {
            res[index] = deepClone(item);
          });
        } else if (typeof obj === 'object' && obj !== null) {
          res = {};
          for (const key in obj) {
            // JavaScript 并没有保护 hasOwnProperty 这个属性名,
            // 可能存在你使用的对象也有这个属性,所以可以使用 Object 原型上的 hasOwnProperty 属性
            if (Object.hasOwnProperty.call(obj, key)) {
              // 偷懒就是直接 obj.hasOwnProperty(key)
              res[key] = deepClone(obj[key]);
            }
          }
          // 用hash值记录防止循环引用
          hash.set(obj, res);
        } else {
          res = obj;
        }
        return res;
      }
    </script>