首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >手写apply/call/bind/new等代码

手写apply/call/bind/new等代码

作者头像
epoos
发布于 2022-06-06 08:11:05
发布于 2022-06-06 08:11:05
2710
举报
文章被收录于专栏:epoos.comepoos.com

1.手写 apply

代码语言:javascript
AI代码解释
复制
Function.prototype.apply1 = function(context = window, args) {
  const fn = Symbol('fn')
  context[fn] = this
  const res = context[fn](...args)
  delete context[fn]
  return res
}

// 思路:将要改变this指向的方法挂到目标this上执行并返回
Function.prototype.apply2 = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  context = context || window
  context.fn = this
  let result
  if (arguments[1]) {
    result = context.fn(...arguments[1])
  } else {
    result = context.fn()
  }
  delete context.fn
  return result
}

2.手写 call

代码语言:javascript
AI代码解释
复制
Function.prototype.call1 = function(context = window, ...args) {
  const fn = Symbol('fn')
  context[fn] = this
  const res = context[fn](...args)
  delete context[fn]
  return res
}

// 思路:将要改变this指向的方法挂到目标this上执行并返回
Function.prototype.call2 = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('not funciton')
  }
  context = context || window
  context.fn = this
  let arg = [...arguments].slice(1)
  let result = context.fn(...arg)
  delete context.fn
  return result
} 

3.手写 bind 方法

代码语言:javascript
AI代码解释
复制
Function.prototype.bind1 = function(context, ...args) {
  let self = this
  return function F() {
    if (this instanceof F) {
      return new self(...args, ...arguments)
    }
    return self.apply(context, [...args, ...arguments])
  }
}


// 思路:类似call,但返回的是函数
Function.prototype.bind2 = function (context) {
  if (typeof this !== 'function') {
    throw new TypeError('Error')
  }
  let _this = this
  let arg = [...arguments].slice(1)
  return function F() {
    // 处理函数使用new的情况
    if (this instanceof F) {
      return new _this(...arg, ...arguments)
    } else {
      return _this.apply(context, arg.concat(...arguments))
    }
  }
}

测试代码:

代码语言:javascript
AI代码解释
复制
var obj = {
  a: 1,
  showA(n, m) {
    return this.a + n + m
  },
}
function test1() {
  this.a = 4
  var s = obj.showA.bind(this, 10)
  console.log('result:',s(20)) // 34
}
function test2() {
  this.a = 2
  var s = obj.showA.apply(this, [1, 2])
  console.log('result:', s) // 5
}
function test3() {
  this.a = 3
  var s = obj.showA.call(this, 2, 3)
  console.log('result:', s) // 8
}
test1()
test2()
test3()

4.实现一个 new

new 关键字调用的基本过程 1)创建一个新对象 2)继承父类原型的方法 3)添加父类属性到新对象上,并初始化,并保存方法的执行结果 4)如果执行结果有返回值,并且是一个对象,返回执行的结果,否则返回新创建的对象

代码语言:javascript
AI代码解释
复制
function _new1(obj, ...args) {
  var newObj = Object.create(obj.prototype)
  var result = obj.apply(newObj, args) // obj里面的this变成了newObj,所以,newObj有了obj的属性
  return (typeof result === 'object' && result !== null ) ? result : newObj
}

function _new2 (fun) {
  return function () {
    // 创建一个新对象且将其隐式原型指向构造函数原型
    let obj = {
      __proto__ : fun.prototype
    }
    // 执行构造函数
    fun.call(obj, ...arguments)
    // 返回该对象
    return obj
  }
}

function Person(firstName, lastName) {
  this.firstName = firstName
  this.lastName = lastName
}
Person.prototype.getFullName = function() {
  return this.firstName + ' ' + this.lastName
}
var newPerson = new Person('jack', 'bob')
var _newPerson = _new(Person, 'jack', 'bob')

5.手写instanceof

代码语言:javascript
AI代码解释
复制
// 思路:右边变量的原型存在于左边变量的原型链上
function instanceOf(left, right) {
  let leftValue = left.__proto__
  let rightValue = right.prototype
  while (true) {
    if (leftValue === null) {
      return false
    }
    if (leftValue === rightValue) {
      return true
    }
    leftValue = leftValue.__proto__
  }
}

6.手写create

代码语言:javascript
AI代码解释
复制
// 思路:将传入的对象作为原型
function create(obj) {
  function F() {}
  F.prototype = obj
  return new F()
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-09-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.手写 apply
  • 2.手写 call
  • 3.手写 bind 方法
  • 4.实现一个 new
  • 5.手写instanceof
  • 6.手写create
领券
社区新版编辑器体验调研
诚挚邀请您参与本次调研,分享您的真实使用感受与建议。您的反馈至关重要,感谢您的支持与参与!
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
首页
学习
活动
专区
圈层
工具
MCP广场
首页
学习
活动
专区
圈层
工具
MCP广场