手写 new, call, apply, bind, reduce, currying柯里化, 防抖节流 源码

实现 new

先用文字描述一下 new 的实现过程

  1. 新定义一个 json 对象
  2. 对象 继承 构造函数的原型链
  3. 将构造函数的 this 指向这个对象
  4. 根据构造函数的返回值类型返回结果,
  function myNew(fn) {
   
    let obj = {
   }
    obj = Object.create(fn.prototype) 
    let args = Array.prototype.slice.call(arguments, 1) // 获取除去fn之外的参数
    let result = fn.call(obj, ...args)
    return typeof result === 'object' ? result : obj;
  }
  function foo() {
   
    this.name = 'ciel'
    this.arg = arguments[0]
  }
  foo.prototype.callName = function() {
   
    console.log(this.name)
  }
  // 测试
  let test = myNew(foo, 'hhh', '123', 'saf')
  test.callName()
  console.log(test.arg)

这里解释一下 return typeof result === ‘object’ ? result : obj; 这句代码:
在JavaScript构造函数中:如果return值类型,那么对构造函数没有影响,实例化对象返回空对象;如果return引用类型(数组,函数,对象),那么实例化对象就会返回该引用类型; 可以测试以下两个构造函数在 new 之后返回的值就可以理解这句话的意思了

 function foo() {
   
   this.name = 'ciel'
   return function() {
   

   }
 }
 new foo() //  fn(){}
 function bar() {
   
   this.name = 'ciel'
   return 1
 }
 new bar() // {name: ciel}

实现 call

先看看伪代码是如何使用 myCall 的 fn.myCall(obj, args) 分析下代码应该怎么实现
myCall 应该挂在 Function.prototype 上
fn 的 this 指向 为 obj
myCall 的 args 透传给 fn

Function.prototype.myCall = function(target, ...args) {
   
  // this 指向调用 myCall函数的对象
  if (typeof this !== "function") {
   
    throw new TypeError("not a function")
  }
  target = target || window
  target.fn = this // 隐式绑定,改变构造函数的调用者间接改变 this 指向
  let result = target.fn(...args)
  return result
};
// 测试
let obj = {
    name: 123 }
function foo(...args) {
   
  console.log(this.name, args)
}
let s = foo.myCall(obj, '111', '222')

实现 apply

回忆一下 apply 与 call 的区别: apply 参数要为数组。 其他和 call 实现一样

Function.prototype.myApply = function(target) {
   
  if (typeof this !== "function") {
   
    throw new TypeError("not a function");
  }
  if (!Array.isArray(arguments[1])) {
   
    throw new Error('arg not a array')
  }
  target = target || window
  target.fn = this
  let args = arguments[1]
  let result = target.fn(args)
  return result
};

const obj = {
    name: 123 };
function foo(...args) {
   
  console.log(this.name, args);
}
foo.prototype.name = 123;
const s1 = [1, 2, 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值