Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

手写实现call, apply,bind #2

Open
YBFACC opened this issue May 29, 2020 · 0 comments
Open

手写实现call, apply,bind #2

YBFACC opened this issue May 29, 2020 · 0 comments

Comments

@YBFACC
Copy link
Owner

YBFACC commented May 29, 2020

本文章的基础

  1. 原型

  2. this的使用

call

介绍

call() 提供新的 this 值给当前调用的函数/方法。你可以使用 call 来实现继承:写一个方法,然后让另外一个新的对象来继承它(而不是在新对象中再写一次这个方法)。来自MDN

使用注意

在非严格模式下,第一个参数如果为null或者undefined时,会自动替换为指向全局对象。

let apple = {
  name: 'apple',
  test: function (price, time) {
    console.log(time, this.name, price)
  }
}
let pear = {
  name: 'pear'
}
//在原型链上绑定方法
Function.prototype._call = function (context, ...args) {
  if (!context || typeof context !== 'object') {
    context = global
  }
  let say = Symbol() // 防止覆盖掉原有属性
  context[say] = this // 这里的this为需要执行的方法
  const res = context[say](...args)
  delete context[say]
  return res
}
apple.test._call(pear, 10, '2020-5-29')//2020-5-29 pear 10

apply

介绍

call()方法的作用和 apply() 方法类似,区别就是call()方法接受的是参数列表,而apply()方法接受的是一个参数数组来自MDN

let apple = {
  name: 'apple',
  test: function (price, time) {
    console.log(time, this.name, price)
  }
}
let pear = {
  name: 'pear'
}
global.name = 'window'//环境为node
apple.test.apply(null, [10, '2020-5-29'])//2020-5-29 window 10

Function.prototype._apply = function (context, args) {
  if (!context || typeof context !== 'object') {
    context = global
  }
  const key = global.Symbol() // 防止覆盖掉原有属性
  context[key] = this // 这里的this为需要执行的方法
  const result = context[key](...args)
  delete context[key]
  return result
}
apple.test._apply(null, [10, '2020-5-29'])//2020-5-29 window 10

apple.test._apply(pear, [10, '2020-5-29']) //2020-5-29 pear 10

bind

介绍

返回一个原函数的拷贝,并拥有指定的 this 值和初始参数。来自MDN

let apple = {
  name: 'apple',
  test: function (price, time) {
    console.log(time, this.name, price)
  }
}
let pear = {
  name: 'pear'
}

//借助call
Function.prototype._bind = function (context) {
  if (!context || typeof context !== 'object') {
    context = global
  }
  return (...args) => {
    this.call(context, ...args)
  }
}
let fun1 = apple.test._bind(pear)
fun1(10, '2020-5-29') //2020-5-29 pear 10
let apple = {
  name: 'apple',
  test: function (price, time) {
    console.log(time, this.name, price)
  }
}
let pear = {
  name: 'pear'
}
Function.prototype._call = function (context, ...args) {
  if (!context || typeof context !== 'object') {
    context = global
  }
  let say = Symbol() // 防止覆盖掉原有属性
  context[say] = this // 这里的this为需要执行的方法
  const res = context[say](...args)
  delete context[say]
  return res
}

//不使用原生call
Function.prototype._bind_ = function (context) {
  if (!context || typeof context !== 'object') {
    context = global
  }
  return (...args) => {
    this._call(context, ...args)
  }
}

let fun2 = apple.test._bind_(pear)
fun2(10, '2020-5-29') //2020-5-29 pear 10

参考

MDN

手写JS函数的call、apply、bind实现

手写call、apply、bind实现及详解

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant