跟着NONO复习day2 - call/apply/bind区别以及手写&浅拷贝&深拷贝&函数柯里化

81 阅读1分钟

call apply bind都可以改变函数调用的this指向,从而改变执行上下文的。

区别在于使用方式不一样,

  1. call()的参数是多个,是立即执行的
  2. apply的参数是一个数组,是立即执行的
  3. bind的参数是多个的,是返回的一个新的函数
Function.prototype.myCall = function (thisArg, ...args) {
    thisArg = thisArg || window
    thisArg.fn = this
    let res = thisArg.fn(...args)
    delete thisArg.fn
    return res
}
    
Function.prototype.myApply = function (thisArg, args) {
    thisArg = thisArg || window
    thisArg.fn = this
    let res = thisArg.fn(...args)
    delete thisArg.fn
    return res
}

Function.prototype.myBind = function (thisArg, args) {
    thisArg = thisArg || window
    thisArg.fn = this;
    return function(...innerArgs){
        const res = thisArg.fn(...args, ...innerArgs);
        return res;
    }
}

浅拷贝 如果属性是基本类型,拷贝的就是基本类型的值,如果属性是引用类型,拷贝的就是内存地址(新旧对象共享同一块内存),所以如果其中一个对象改变了这个地址,就会影响到另一个对象。

1. obj2 = {...obj1,}
2. object.assign
3. concat()
4. slice()

深拷贝 深拷贝是将一个对象从内存中完整的拷贝一份出来,从堆内存中开辟一个新的区域存放新对象

// 深拷贝
const deepCopy = (target) => {
  const checkType = (_target) => { return Object.prototype.toString.call(_target) } 
  let res;
  if(checkType(target) === '[object Object]') res = {};
  if(checkType(target) === '[object Array]') res = [];
  for(let key in target){
    if(target[key] === '[object Object]' || target[key] === '[object Array]'){
      res[key] = clone(target[key])
    } else {
      res[key] = target[key]
    }
  };
  return res;
};

函数柯里化本质上是就是把多个参数累计起来一块塞到初始的函数里去执行。

const curry = (fn, ...args) => {
    return args.length >= fn.length ? fn(...args) : (..._args) => fn(...args, ..._args);
}
function add1(x, y, z) {
  return x + y + z;
}
const add = curry(add1);
console.log(add(1, 2, 3));
console.log(add(1)(2)(3));
console.log(add(1, 2)(3));
console.log(add(1)(2, 3));