js试题整理

洗牌:

function shuffle(arr) {
    let i = arr.length;
    while (i) {
        let j = Math.floor(Math.random() * i--);
        [arr[j], arr[i]] = [arr[i], arr[j]];
    }
}

柯力化:

function add() {
    // 第一次执行时,定义一个数组专门用来存储所有的参数
    var _args = Array.prototype.slice.call(arguments);

    // 在内部声明一个函数,利用闭包的特性保存_args并收集所有的参数值
    var _adder = function() {
        _args.push(...arguments);
        return _adder;
    };

    // 利用toString隐式转换的特性,当最后执行时隐式转换,并计算最终的值返回
    _adder.toString = function () {
        return _args.reduce(function (a, b) {
            return a + b;
        });
    }
    return _adder;
}

let s = add(1)(2)(3)
console.log(s)

相加:

function one(arg=0){
	return arg + 1
}
function two(arg=0){
	return arg + 2
}
function add(arg){
	return arg
}
two(add(one()))

new实现:

// 第二版
function create() {
    // 创建一个空的对象
    var obj = new Object(),
    // 获得构造函数,arguments中去除第一个参数
    Con = [].shift.call(arguments);
    // 链接到原型,obj 可以访问到构造函数原型中的属性
    obj.__proto__ = Con.prototype;
    // 绑定 this 实现继承,obj 可以访问到构造函数中的属性
    var ret = Con.apply(obj, arguments);
    // 优先返回构造函数返回的对象
    return typeof ret === 'object' ? ret : obj;
};

bind实现:

// 第四版,已通过测试用例
Function.prototype.bind2 = function (context) {
    var self = this;
    var args = Array.prototype.slice.call(arguments, 1);
    var fNOP = function () {};
    var fBound = function () {
        var bindArgs = Array.prototype.slice.call(arguments);
        return self.apply(
            this instanceof fNOP ? this : context, 
            args.concat(bindArgs)
        );
    }
    fNOP.prototype = this.prototype;
    fBound.prototype = new fNOP();
    return fBound;
}

call、apply

Function.prototype.call = function (context) {
  context = context || window;
  context.fn = this;

  let args = [...arguments].slice(1);
  let result = context.fn(...args);

  delete context.fn
  return result;
}
Function.prototype.apply = function (context, arr) {
    context = context || window;
    context.fn = this;

    let result;
    if (!arr) {
        result = context.fn();
    } else {
        result = context.fn(...arr);
    }

    delete context.fn
    return result;
}

promise.all:

all(list) {
        return new Promise((resolve, reject) => {
            let resValues = [];
            let counts = 0;
            for (let [i, p] of list) {
                resolve(p).then(res => {
                    counts++;
                    resValues[i] = res;
                    if (counts === list.length) {
                        resolve(resValues)
                    }
                }, err => {
                    reject(err)
                })
            }
        })
    }

finally:

Promise.prototype.finally = function (callback) {
  let P = this.constructor;
  return this.then(
    value  => P.resolve(callback()).then(() => value),
    reason => P.resolve(callback()).then(() => { throw reason })
  );
};

race:

Promise._race = promises => new Promise((resolve, reject) => {
	promises.forEach(promise => {
		promise.then(resolve, reject)
	})
})

扁平化:

Array.from(new Set(arr.flat(Infinity))).sort((a,b)=>{ return a-b})
Array.prototype.flat= function() {
    return [].concat(...this.map(item => (Array.isArray(item) ? item.flat() : [item])));
}
function flatten(arr) {
    while (arr.some(item => Array.isArray(item))) {
        arr = [].concat(...arr);
    }
    return arr;
}

指定层级和获取深度:

var arrs = [[],[[],[1,[1,[1]]]]], floor = 1, max = 1;
function deep(arr, floor){
	arr.map(item => {
		if(max < floor){max = floor}
		if(item instanceof Array){
			deep(item, floor+1)
		}
	})
}
deep(arrs,1)
console.log(max) //5

function flatten(arr,n=1){
  let result = arr
  while(n--){
    result = shallowFlatten(result)
  }
  return result 
}
function shallowFlatten(arr){
    return [].concat.apply([],arr)
}
flatten([1,[2,[3,[4]]]], n=1)

async\await

async function fn(args) {
  // ...
}

// 等同于

function fn(args) {
  return spawn(function* () {
    // ...
  });
}
function spawn(genF) {
  return new Promise(function(resolve, reject) {
    const gen = genF();
    function step(nextF) {
      let next;
      try {
        next = nextF();
      } catch(e) {
        return reject(e);
      }
      if(next.done) {
        return resolve(next.value);
      }
      Promise.resolve(next.value).then(function(v) {
        step(function() { return gen.next(v); });
      }, function(e) {
        step(function() { return gen.throw(e); });
      });
    }
    step(function() { return gen.next(undefined); });
  });
}

对象判断:

export default function isPlainObject(obj) {
  if (typeof obj !== 'object' || obj === null) return false

  let proto = Object.getPrototypeOf(obj)

  if (proto === null) return true

  let baseProto = proto
  while (Object.getPrototypeOf(baseProto) !== null) {
    baseProto = Object.getPrototypeOf(baseProto)
  }

  return proto === baseProto
}

promise:promise
vuex原理补充:vuex原理补充
redux原理补充:redux原理补充
react-redux原理补充:react-redux原理补充
redux-saga原理补充:添加链接描述
react+diff原理补充:react简易实现
react-router原理:react-router原理
react fiber原理补充:原理分析
vue原理补充: vue原理补充
webpack热更新原理补充: webpack热更新原理补充
webpack代码分割打包原理补充:webpack代码分割打包原理补充
koa原理补充:项目地址
grahql补充:----------------
vue通信:------------------
react-form:-----------------
diff原理:添加链接描述
事件合成机制添加链接描述
react setSate机制:

1.enqueueSetState将state放入队列中,并调用enqueueUpdate处理要更新的Component
2.如果组件当前正处于update事务中,则先将Component存入dirtyComponent中。否则调用batchedUpdates处理。
3.batchedUpdates发起一次transaction.perform()事务
4.开始执行事务初始化,运行,结束三个阶段
5.初始化:事务初始化阶段没有注册方法,故无方法要执行
6.运行:执行setSate时传入的callback方法,一般不会传callback参数
7.结束:更新isBatchingUpdates为false,并执行FLUSH_BATCHED_UPDATES这个wrapper中的close方法
8.FLUSH_BATCHED_UPDATES在close阶段,会循环遍历所有的dirtyComponents,调用updateComponent刷新组件,并执行它的pendingCallbacks, 也就是setState中设置的callback。

你可能感兴趣的:(web前端开发)