A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 逆风TO 于 2020-3-18 14:54 编辑

考查 thiscall、apply
[JavaScript] 纯文本查看 复制代码
Function.prototype._call = function(ctx = window, ...args) {[/b]  const fnKey = 'tmp_' + Date.now();
  ctx[fnKey] = this;
  const result = ctx[fnKey](...args);
  delete ctx[fnKey];
  return result;
};

// 第二个参数是数组
Function.prototype._apply = function(ctx = window, args = []) {
  const fnKey = 'tmp_' + Date.now();
  ctx[fnKey] = this;
  const result = ctx[fnKey](...args);
  delete ctx[fnKey];
  return result;
};

let obj = { x: 1 };
function fn() {
  console.log(this.x, arguments);
}
fn._call(obj, 1, 2, 3);
fn._apply(obj, [1, 2, 3]);
bind
[JavaScript] 纯文本查看 复制代码
Function.prototype._bind = function() {
  const slice = [].slice;
  const _fn = this;
  const ctx = arguments[0];
  const args = slice.call(arguments, 1);
  if (typeof _fn !== 'function') {
    throw new TypeError('Function.prototype.bind - ' +
      'what is trying to be bound is not callable');
  }
  return function() {
    const funcArgs = args.concat(slice.call(arguments));
    return _fn.apply(ctx, funcArgs);
  };
};

const obj = { x: 1 };
function A() {
  console.log(this.x);
}
const fn = A._bind(obj);
fn();

new
[JavaScript] 纯文本查看 复制代码
function newObject(fn) {
  const obj = {};
  const res = fn.apply(obj, [].slice.call(arguments, 1));
  return res instanceof Object ? res : obj;
}

function Con(a) {
  this.a = a;
}
const obj = newObject(Con, 1);

链式调用
[JavaScript] 纯文本查看 复制代码
Number.prototype.add = function(num) {
  num = +num;
  if(num !== num) return Number(this);
  return Number(this + num);
};

let n = 1;
n.add(1).add(2).add(3);

考查原型链
[JavaScript] 纯文本查看 复制代码
function instance_of(lhs, rhs) {
  while (lhs) {
    lhs = lhs.__proto__;
    if (lhs === rhs.prototype) return true;
  }
  return false;
}

组合寄生继承
[JavaScript] 纯文本查看 复制代码
function Super(){}
function Sub() {
    Super.call(this); // 继承自有属性
}

// 继承原型链上的属性和方法
Sub.prototype = Object.create(Super.prototype); // 继承原型链
Sub.prototype.constructor = Sub;

Object.create
[JavaScript] 纯文本查看 复制代码
if(!Object.create) {
  Object.create = function(proto) {
    function F(){}
    F.prototype = proto;
    return new F;
  }
}

纯对象
[JavaScript] 纯文本查看 复制代码
function isPlainObject(obj) {
  if (typeof obj !== 'object' || obj === null) return false;
  var proto = obj;

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

  return Object.getPrototypeOf(obj) === proto;
}

function A() {}
isPlainObject( new A );      // false
isPlainObject( new Object ); // true
isPlainObject( {} );         // true

判断类型
[JavaScript] 纯文本查看 复制代码
const type = 'Boolean Number String Function Array Date RegExp Object Error Symbol'
  .split(' ')
  .reduce((pre, name) => {
    pre[`[object ${name}]`] = name.toLowerCase();
    return pre;
  }, {});

function toType( obj ) {
  if ( obj == null ) {
    return obj + '';
  }

  return typeof obj === 'object' || typeof obj === 'function' ?
    type[ Object.prototype.toString.call( obj ) ] || 'object' :
    typeof obj;
}

toType(/xxx/) // regexp

考查闭包柯里化
[JavaScript] 纯文本查看 复制代码
function curry(fn, ...args) {
  if(args.length >= fn.length) {
    return fn.apply(null, args);
  }

  return (...args2) => curry(fn, ...args, ...args2);
}

const add = curry(function(a, b, c) {
  return a + b + c;
});
add(1, 2, 3);
add(1)(2)(3);
add(1, 2)(3);
add(1)(2, 3);

考查性能意识防抖
[JavaScript] 纯文本查看 复制代码
function debounce(fn, delay) {[/b]  let timer = null;
  return function() {
    // 中间态一律清除掉
    timer && clearTimeout(timer);
    // 只需要最终的状态,执行
    timer = setTimeout(() => fn.apply(this, arguments), delay);
  };
}

节流
[JavaScript] 纯文本查看 复制代码
function throttle(fn, delay) {[/b]  let timer, lastTime;
  return function() {
    const now = new Date().getTime();
    const space = now - lastTime; // 间隔时间
    if( lastTime && space < delay ) { // 为了响应用户最后一次操作
      // 非首次,还未到时间,清除掉计时器,重新计时。
      timer && clearTimeout(timer);
      // 重新设置定时器
      timer = setTimeout(() => {
        lastTime = now; // 不要忘了记录时间
        fn.apply(this, arguments);
      }, delay);
      return;
    }
    // 首次或到时间了
    lastTime = now;
    fn.apply(this, arguments);
  };
}
事件代理
[JavaScript] 纯文本查看 复制代码
function delegate(ele, selector, type, fn) {
  function callback(e) {
    e = e || window.event;
    const target = e.target || e.srcElement;
    if( ele.contains(target) ) {
      fn.call(target, e);
    }
  }
  ele.addEventListener(type, callback, false);
}

delegate(document.querySelector('body'), 'button', 'click', function () {
  console.log('bingo');
});

限制并发数

[JavaScript] 纯文本查看 复制代码
function sendRequest(urls, max, callback) {
  let last = performance.now();
  let len = urls.length;
  let limit = max; // 控制并发数
  let cnt = 0;     // 累积执行任务数
  let res = [];    // 有序存储执行结果
  const tasks = urls.map((url, index) => () => fetch(url)
    .then(data => {
      res[index] = data;
    })
    .catch(reason => {
      res[index] = reason;
    })
    .finally(() => {
      if( ++cnt === len ) return callback(res);
      ++limit;
      doTasks();
    }));

  doTasks();

  function doTasks() {
    while( limit && tasks.length ) {
      --limit;
      let task = tasks.shift();
      task();
      console.log(`执行间隔:${performance.now() - last}`);
    }
  }
}

// 模拟 fetch
function fetch(url) {
  return new Promise(function (resolve, reject) {
    let good, bad;
    const time = 3000;

    good = setTimeout(function () {
      clearTimeout(bad);
      let data = `resolve: ${url}`;
      resolve(data);
      console.log(data);
    }, Math.random() * time);

    bad = setTimeout(function () {
      clearTimeout(good);
      let reason = `reject: ${url}`;
      reject(reason);
      console.log(reason);
    }, Math.random() * time);
  });
}

// 测试
sendRequest([1,2,3,4,5,6,7,8,9,10], 5, (res) => console.log('all done:' + res));



0 个回复

您需要登录后才可以回帖 登录 | 加入黑马