亮神知识库 亮神知识库
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)

亮神

前程明亮,未来可期
首页
  • 手写代码

    • 手写代码系列
  • 基础知识

    • 基础
    • JS底层
    • CSS
  • 原理
  • 浏览器
  • HTTP
  • 网络安全
  • babel
  • webpack基础
  • webpack进阶
  • Vite
  • TypeScript
  • Vue2
  • Vue3
  • Node基础

    • glob
    • 模块化机制
    • 事件循环
    • KOA2框架原理
    • Node子进程
    • cluster原理(了解)
  • 教育行业2021

    • B端
    • C端
    • 工具
  • 游戏行业2025
  • 刷题
  • 杂(待整理)
  • 学习
  • 面试
  • 实用技巧
  • 心情杂货
  • 年度总结
  • 友情链接
关于
  • 分类
  • 标签
  • 归档
  • 收藏
GitHub (opens new window)
  • 基础

  • 手写代码

    • 手写类型转换
    • 手写累加、累乘函数
    • 手写new
    • 手写深拷贝
    • 手写Object.create
    • 手写继承
    • 手写extends
    • 手写instanceof
    • 手写call、apply、bind
      • 手写call、apply
      • 手写bind(待整理)
    • 手写jsonp
    • 手写getQueryString
    • 手写setInterval
    • 手写防抖与节流
    • 手写对象属性值迭代器
    • 手写分时函数
    • 手写事件委托
    • 手写图片懒加载
    • 手写原生Ajax请求
    • 手写AOP装饰函数
    • 手写柯里函数
    • 手写数组扁平化flat
    • 手写数组去重
    • 手写eventEmit类
    • 手写Vue数据响应式
    • 手写Vue nextTick
    • 手写Promise
  • JS底层深入

  • CSS

  • 基础
  • 手写代码
0zcl
2021-06-18
目录

手写call、apply、bind

JS <code>call</code>、<code>apply</code>和<code>bind</code> 的区别?

  • call 接受多个参数,apply 接受 一个包含多个参数的数组
  • call和apply本质上是直接调用了函数,而bind是返回一个绑定了上下文的函数
var value = 1;
function bar() {
    console.log(this.value);
}
bar.call(null); // 1

var foo = {
    value: 1
};
function bar(name, age) {
    return {
		value: this.value,
		name: name,
		age: age
    }
};
bar.call(foo, "Jack", 20); // {value: 1, name: "Jack", age: 20}
var bindFoo1 = bar.bind(foo, "Jack", 20); // 返回一个函数
bindFoo1(); // {value: 1, name: "Jack", age: 20}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

<strong>this 参数可以传 null,当为 null 的时候,视为指向 window</strong>

思路:A.call(B, args) 和 A.apply(B, [args]) 本质上是执行A,A的this指向是B。那其实 B.A() 的形式来调用A函数, 即可

# 手写call、apply

注意

实现call

答:

Function.prototype.call2 = function(context) { // context 相当于 B
  context = context || window // this 相当于 A
  context.fn = this  // 相当于 B.A()
  const args = [...arguments].slice(1)
  const res =  context.fn(...args)
  delete context.fn
  return res
}

// 测试
var value = 1;
var foo = {
  value: 2
};
function bar() {
  console.log(this.value);
}
bar.call2(foo) // 2
bar.call2(null) // 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

根据思路来,其实实现call也很简单,注意:B.A() 给B额外添加属性方法A,执行方法A后,要给B去除这个属性

注意

实现apply

答:实现了call,实现apply也基本一样的. A.apply(B, [args]) 转成 B.A()

Function.prototype.apply2 = function(context) {
  context = context || window
  context.fn = this
  const args = [...arguments].slice(1)
  const res = context.fn(args)
  return res
}

// 测试
var value = 1;
var foo = {
  value: 2
};
function bar() {
  console.log(this.value);
}
bar.apply2(foo) // 2
bar.apply2(null) // 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18

注意:直接调类数组 arguments.slice() 会爆错

# 手写bind(待整理)

注意

实现bind

先来看下bind的使用,最近初学写react, 也常用到bind

var value = 2;
var foo = {
    value: 1
};
function bar(name, age) {
    return {
		value: this.value,
		name: name,
		age: age
    }
};

bar.call(foo, "Jack", 20); // {value: 1, name: "Jack", age: 20}
var bindFoo1 = bar.bind(foo, "Jack", 20); // 返回一个函数
bindFoo1(); // {value: 1, name: "Jack", age: 20}
var bindFoo2 = bar.bind(foo, "Jack"); // 返回一个函数
bindFoo2(20); // {value: 1, name: "Jack", age: 20}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

四个特点:

  • 可以指定this
  • 返回一个函数
  • 可以传入参数
  • 柯里化: 在函数调用时只传递一部分参数进行调用,函数会返回一个新函数去处理剩下的参数

参考:前端必会的手写实现面试题——bind (opens new window)

编辑 (opens new window)
上次更新: 2025/07/17, 07:17:44
手写instanceof
手写jsonp

← 手写instanceof 手写jsonp→

最近更新
01
2024年
07-20
02
2023年
07-20
03
2022年
07-20
更多文章>
Theme by Vdoing | Copyright © 2025-2025 亮神 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式