Saber2pr's Blog



// 对象作用域
const objContext = {
  value: 1,
  getValue(v1, v2) {
    if (v1 && v2) return v1 + v2 + this.value
    return this.value
// 获取对象作用域内的函数
const method = objContext.getValue

// 函数作用域下(父作用域不能访问子作用域!)
console.log(method()) // undefined

// 手动转移(绑定、指定)执行上下文到objContext上下文中
console.log(method.apply(objContext)) // 1
console.log( // 1
console.log(method.bind(objContext)()) // 1

Implement call

Function.prototype.myCall = function(thisArg, ...argArray) {
  // Symbol是es6增加的第六个基本类型,对于对象属性就是uuid
  const id = Symbol()
  // 获取要指定的上下文
  context = thisArg || window
  // 将当前函数链接到指定的上下文中
  context[id] = this
  // 当前函数在context上下文中执行
  const result = context[id](...argArray)
  // 移除context中已执行的当前函数
  delete context[id]
  // 返回结果
  return result

Implement bind

Function.prototype.myBind = function(thisArg, ...argArray) {
  return () => this.myCall(thisArg, ...argArray)

Implement apply

Function.prototype.myApply = function(thisArg, argArray = []) {
  return this.myCall(thisArg, ...argArray)
console.log(Math.max.myCall(null, ...[1, 2, 3])) // 3

console.log(method.myApply(objContext, [1, 2])) // 4
console.log(method.myCall(objContext, 1, 2)) // 4
console.log(method.myBind(objContext, 1, 2)()) // 4


To sum up.

The core is the implementation of call. In fact, it would be nice to implement either apply or bind. (thisArg,… items) If you don't read the context inside a function, call doesn't make a difference. The reason is that the context in which the js function executes is not always the same as the context in which the declaration is made, that is, this is a dynamic value. So in order to avoid errors when calling this within a function, you usually bind call to the context in which you declare it. So what call needs to do:

  1. Since this itself is a function within the call function, binding is done by assigning this directly to the property of context two。 Declare a new function value pointing to this in context, and then call the new function with object scope In fact, the binding implemented by the obj [method]method is used to create a new function in the obj that points to the current and then executes, and obj is used as the context to call its own properties.