源码5——const/new/instanceof/函数柯里化

1. js实现const

function myConst (key, value) {
  const desc = {
    value: value,
    writable: false
  }
  Object.defineProperty(window, key, desc);
}

myConst('obj', {a: 1})

2. js实现new

function myNew (fn, params) { // 构造函数,构造函数参数
  const args = Array.prototype.slice.call(arguments);
  const fn = args.shift();

  const obj = Object.create(fn.prototype);  // this对象
  const res = fn.apply(obj, args);  // 如果return的是一个对象,new命令直接返回该对象,否则返回this对象
  return (typeof res === 'object' && typeof res !=='null') ? res : obj;
}

var p = myNew(Person, '张三',  28)

3. js实现instanceof

// 模拟 left instanceof right,
function isInstanceof(left, right){
  // object和null排除,因为后面追溯原型要用到
  const baseType = ['number', 'string', 'boolean', 'undefined', 'symbol'];
  if(baseType.includes(typeof(left)))  return false;
  // 将right.prototype依次和left原型链上的每个对象做比较
  left = left.__proto__;
  while(true){
      if(left === null)   return false;
      if(left === right.prototype)  return true;
      left = left.__proto__;
  }
}

4. 实现柯里化

将一个多参函数转换成一系列的单参函数,而部分应用则是将一个多参函数切一刀,柯里化是切好多刀,直到中间每个函数都是单参的,最后得到柯里化函数。

(1)与普通函数的对比示例:

const add = function(x, y, z) {
  return x + y + z;
}

const curAdd = currying(add);   //传入多参函数
const res = curAdd(1)(2)(3);   // 调用柯里化函数
console.log(res);   // 6

(2)js实现

function toCurry(fn, ...args) {
  return function () {
    // 合并上一次缓存的参数和本次传入的参数
    args = [...args, ...arguments];
    // 判断参数数量是否等于原函数的参数个数
    // fn.length表示函数定义时的参数个数
    if (args.length < fn.length) {
      // 不够的话,继续递归
      return toCurry(fn, ...args);
    } else {
      // 数量足够,执行函数并返回结果
      return fn.apply(null, args);
    }
  }
}

上一篇:面向对象05多态


下一篇:instanceof和类型转换