JS中bind、call和apply的作用以及在TS装饰器中的用法
1,前言
bind
、call
和apply
在函数式编程时候非常有用,本文旨在记录一下我遇到过的一些用法和知识点,也记录一下在装饰器中的用法。
1,call
call()
方法使用一个指定的this
值和单独给出的一个或多个参数来调用一个函数。它的第一个参数是你需要指向的this
目标,后面的参数是你需要传递的参数,无参数可以不写。
语法:
function.call(target, arg1, arg2, ...)
1.1,例子
如下,控制台会打印出:快看【张三】在奔跑
const Person = {
Name: '张三',
Run() {
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run()) // 打印出:快看【张三】在奔跑
让我们使用call
改变下this
指向
1.2,直接调用
如果没有传递第一个参数,this
的值将会被绑定为全局对象,也就是window
对象(浏览器环境)。由于在window
上找不到this.Name
这个属性,控制台会打印出:快看【undefined】在奔跑
console.log(Person.Run.call()) // 打印出:快看【undefined】在奔跑
1.3,将this指向另一个对象
此时this
会绑定为被指向的对象,控制台会打印出:快看【猛犸象】在奔跑
console.log(Person.Run.call(Animal)) // 打印出:快看【猛犸象】在奔跑
1.4,传递参数
const Person = {
Name: '张三',
Run(param1, param2) {
console.log(param1)
console.log(param2)
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run.call(Animal, 10, '100')) // 打印出:10、'100'、快看【猛犸象】在奔跑
2,apply
apply()
方法调用一个具有给定this
值的函数,以及以一个数组(或类数组对象)的形式提供的参数。它的第一个参数是你需要指向的this
目标,后面的参数是你需要传递的数组参数,无参数可以不写。
语法:
function.apply(target, [argsArray])
2.1,例子
如下,控制台会打印出:快看【张三】在奔跑
const Person = {
Name: '张三',
Run() {
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run()) // 打印出:快看【张三】在奔跑
让我们使用apply
改变下this
指向
2.2,直接调用
如果没有传递第一个参数,this
的值将会被绑定为全局对象,也就是window
对象(浏览器环境)。由于在window
上找不到this.Name
这个属性,控制台会打印出:快看【undefined】在奔跑
console.log(Person.Run.apply()) // 打印出:快看【undefined】在奔跑
2.3,将this指向另一个对象
此时this
会绑定为被指向的对象,控制台会打印出:快看【猛犸象】在奔跑
console.log(Person.Run.apply(Animal)) // 打印出:快看【猛犸象】在奔跑
2.4,传递参数
const Person = {
Name: '张三',
Run(...arg) {
console.log(arg)
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run.apply(Animal, [10, '100'])) // 打印出:[10、'100']、快看【猛犸象】在奔跑
2.5,合并数组
let arr = ['a', 'b']
let elements = [0, 1, 2]
array.push.apply(arr, elements)
console.log(arr) // ["a", "b", 0, 1, 2]
3,bind
bind()
方法创建一个新的函数,在bind()
被调用时,这个新函数的this
被指定为bind()
的第一个参数,而其余参数将作为新函数的参数,供调用时使用。
语法:
function.bind(target, arg1, arg2, ...)
3.1,例子
如下,控制台会打印出:快看【张三】在奔跑
const Person = {
Name: '张三',
Run() {
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run()) // 打印出:快看【张三】在奔跑
让我们使用apply
改变下this
指向
3.2,直接调用
如果没有传递第一个参数,this
的值将会被绑定为全局对象,也就是window
对象(浏览器环境)。由于在window
上找不到this.Name
这个属性,控制台会打印出:快看【undefined】在奔跑
注意:bind
返回的是一个方法,需要加上()
执行才行
console.log(Person.Run.bind()()) // 打印出:快看【undefined】在奔跑
3.3,将this指向另一个对象
此时this
会绑定为被指向的对象,控制台会打印出:快看【猛犸象】在奔跑
console.log(Person.Run.bind(Animal)()) // 打印出:快看【猛犸象】在奔跑
3.4,传递参数
const Person = {
Name: '张三',
Run(param1, param2) {
console.log(param1)
console.log(param2)
return `快看【${this.Name}】在奔跑`
}
}
const Animal = {
Name: '猛犸象'
}
console.log(Person.Run.bind(Animal, 996, '100')()) // 打印出:996 '100' 快看【猛犸象】在奔跑
4,TypeScript中装饰器使用
使用bind
或者apply
或者call
,可以将方法装饰器中的this
指向被装饰的方法,不影响原方法使用的同时,注入新的逻辑处理。
function GetHttp(param: string) {
return function (target: any, Name: any, desc: any): void {
console.log(target) // 原型
console.log(Name) // 方法名
console.log(desc) // 方法描述 desc.value即是该方法
const ev = desc.value
desc.value = function(): void {
console.log('我是改写后的function')
ev.call(this)
}
}
}
class HttpGet {
name: string
constructor(name: string) {
this.name = name
}
@GetHttp('方法装饰器')
request(): void {
console.log(this.name)
}
}
const HttpObj = new HttpGet('小红')
HttpObj.request()
// 打印出:方法装饰器、我是改写后的function、小红
5,总结
5.1,相同点
- 都可以通过指定第一个参数,改变
this
指向 - 都可以传递参数
5.2,不同点
bind
返回的是一个函数,需要加上()
来执行apply
传递参数需要数组的形式
如果看了觉得有帮助的,我是@鹏多多,欢迎 点赞 关注 评论;END
PS:在本页按F12,在console中输入document.querySelectorAll('.diggit')[0].click(),有惊喜哦
公众号
往期文章
- 助你上手Vue3全家桶之Vue-Router4教程
- 助你上手Vue3全家桶之Vue3教程
- 助你上手Vue3全家桶之VueX4教程
- 使用nvm管理node.js版本以及更换npm淘宝镜像源
- 超详细!Vue-Router手把手教程
- vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
- 微信小程序实现搜索关键词高亮
- 超详细!Vue的九种通信方式
- 超详细!Vuex手把手教程
个人主页
JS中bind、call和apply的作用以及在TS装饰器中的用法的更多相关文章
- python_如何修改装饰器中参数?
案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...
- 快速理解js中的call,apply的作用
今天被人问到js中的call,apply的区别和用途,解释了一番后,想到之前在逼乎上看到一位小伙伴生动形象的解释 本身不难理解,看下MDN就知道了,但是不常用,遇到了,还要脑回路回转下.或者时间长了, ...
- python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变
Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...
- 【转】odoo 新API装饰器中one、model、multi的区别
http://blog.csdn.net/qq_18863573/article/details/51114893 1.one装饰器详解 odoo新API中定义方式: date=fields.Date ...
- 装饰器中functools的用处
定义一个最简单的装饰器 def user_login_data(f): def wrapper(*args, **kwargs): return f(*args, **kwargs) return w ...
- 装饰器中的@functools.wraps的作用
def login_required(view_func): @functools.wraps(view_func) def wrapper(*args, **kwargs): ...... retu ...
- python装饰器中functools.wraps的作用详解
直接上代码看效果: # 定义一个最简单的装饰器 def user_login_data(f): def wrapper(*args, **kwargs): return f(*args, **kwar ...
- python装饰器中的计时器thd.strat用法
thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) thd.start() thd.join(seconds) alive = th ...
- JSP和Servlet中的几个编码的作用及原理
首先,说说JSP和Servlet中的几个编码的作用. 在JSP和Servlet中主要有以下几个地方可以设置编码,pageEncoding="UTF-8".contentType=& ...
随机推荐
- 反调试——7——CRC检测
反调试--7--CRC检测 CRC32: CRC的全称是循环冗余校验,作用是为了检测数据的完整性. CRC32的检测原理: 程序被编译后,代码段是固定的,因为已经被写死了. 我们在调试程序的时候,打断 ...
- tomcat启动程序报错
1.问题 23-Apr-2021 10:53:38.897 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.de ...
- Go语言核心36讲(Go语言基础知识二)--学习笔记
02 | 命令源码文件 我们已经知道,环境变量 GOPATH 指向的是一个或多个工作区,每个工作区中都会有以代码包为基本组织形式的源码文件. 这里的源码文件又分为三种,即:命令源码文件.库源码文件和测 ...
- 使用 PyTorch Lightning 将深度学习管道速度提高 10 倍
前言 本文介绍了如何使用 PyTorch Lightning 构建高效且快速的深度学习管道,主要包括有为什么优化深度学习管道很重要.使用 PyTorch Lightning 加快实验周期的六种 ...
- 洛谷4103 HEOI2014大工程(虚树+dp)
又是一道虚树好题啊 我们建出来虚树,然后考虑dp过程,我们分别令\(sum[x],mndis[x],mxdis[x],size[x]\)为子树内的路径长度和,最短链,最长链,子树内关键点个数. 对于一 ...
- hibernate不同条件查询结果集一样,主键@ID的原因
这一周在翻新公司的老项目,遇到了一些预想不到的事情. 其中一个是,使用hibernate查询,不同的查询条件,居然都查到同一条记录,感觉奇怪了,开始以为是session的原因: 后来发现是hibern ...
- NXOpen.BlockStyler的一些用法
关于BLOCK UI的一些控件的用法,本人曾经使用的代码,拿出来共享: Option Strict Off Imports NXOpen Imports NXOpen.BlockStyler Impo ...
- 用C++生成solidity语言描述的buchi自动机的初级经验
我的项目rvtool(https://github.com/Zeraka/rvtool)中增加了生成solidity语言格式的监控器的模块. solidity特殊之处在于,它是运行在以太坊虚拟机环境中 ...
- 【UE4 C++ 基础知识】<10>资源的引用
2种引用方式 硬引用(Hard Reference) 即对象 A 引用对象 B,并导致对象 B 在对象 A 加载时加载 硬引用过多会导致运行时很多暂时用不到的资源也被加载到内存中 大量资源会导致进程阻 ...
- zlib开发笔记(四):zlib库介绍、编译windows vs2015x64版本和工程模板
前言 Qt使用一些压缩解压功能,介绍过libzip库编译,本篇说明zlib库.需要用到zlib的msvc2015x64版本,编译一下. 版本编译引导 zlib在windows上的mingw32 ...