1,前言


bindcallapply在函数式编程时候非常有用,本文旨在记录一下我遇到过的一些用法和知识点,也记录一下在装饰器中的用法。

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(),有惊喜哦


公众号

往期文章

个人主页

JS中bind、call和apply的作用以及在TS装饰器中的用法的更多相关文章

  1. python_如何修改装饰器中参数?

    案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...

  2. 快速理解js中的call,apply的作用

    今天被人问到js中的call,apply的区别和用途,解释了一番后,想到之前在逼乎上看到一位小伙伴生动形象的解释 本身不难理解,看下MDN就知道了,但是不常用,遇到了,还要脑回路回转下.或者时间长了, ...

  3. python装饰器中@wraps作用--修复被装饰后的函数名等属性的改变

    Python装饰器(decorator)在实现的时候,被装饰后的函数其实已经是另外一个函数了(函数名等函数属性会发生改变),为了不影响,Python的functools包中提供了一个叫wraps的de ...

  4. 【转】odoo 新API装饰器中one、model、multi的区别

    http://blog.csdn.net/qq_18863573/article/details/51114893 1.one装饰器详解 odoo新API中定义方式: date=fields.Date ...

  5. 装饰器中functools的用处

    定义一个最简单的装饰器 def user_login_data(f): def wrapper(*args, **kwargs): return f(*args, **kwargs) return w ...

  6. 装饰器中的@functools.wraps的作用

    def login_required(view_func): @functools.wraps(view_func) def wrapper(*args, **kwargs): ...... retu ...

  7. python装饰器中functools.wraps的作用详解

    直接上代码看效果: # 定义一个最简单的装饰器 def user_login_data(f): def wrapper(*args, **kwargs): return f(*args, **kwar ...

  8. python装饰器中的计时器thd.strat用法

    thd = KThread(target=_new_func, args=(), kwargs=new_kwargs) thd.start() thd.join(seconds) alive = th ...

  9. JSP和Servlet中的几个编码的作用及原理

    首先,说说JSP和Servlet中的几个编码的作用. 在JSP和Servlet中主要有以下几个地方可以设置编码,pageEncoding="UTF-8".contentType=& ...

随机推荐

  1. Linear Referencing Tools(线性参考工具)

    线性参考工具 # Process: 创建路径 arcpy.CreateRoutes_lr("", "", 输出路径要素类, "LENGTH" ...

  2. iOS自定义拍照框拍照&裁剪(一)

    卡片机时代 很重要的一点是,相机本身是没有方向概念的,它不理解拍摄的内容,只会以相机自己的坐标系去保存数据,下图展示了相机对"F"进行四个角度拍摄时返回的图片数据. 最初的卡片机时 ...

  3. 使用ShardingSphere-JDBC完成Mysql的分库分表和读写分离

    1. 概述 老话说的好:选择比努力更重要,如果选错了道路,就很难成功. 言归正传,之前我们聊了使用 MyCat 实现Mysql的分库分表和读写分离,MyCat是服务端的代理,使用MyCat的好处显而易 ...

  4. python socket 基本使用

    socket通常也叫做"套接字",用于连接server client,是一个通信链的句柄,应用程序通常通过套接字向网络发出请求或应答网络请求. 就像python 处理file一样: ...

  5. mall笔记

    介绍 SpringBoot.SpringCloud.SpringCloudAlibaba.Nacos.Sentinel.Seata整合demo. 软件架构 JDK 1.8 Spring Boot 2. ...

  6. 【数据结构与算法Python版学习笔记】图——强连通分支

    互联网 我们关注一下互联网相关的非常巨大图: 由主机通过网线(或无线)连接而形成的图: 以及由网页通过超链接连接而形成的图. 网页形成的图 以网页(URI作为id)为顶点,网页内包含的超链接作为边,可 ...

  7. [调试笔记] 晚测5 T1 容易题

    众所周知,sbwzx在考试一结束就嚷嚷T1是个sb题.那他为什么调了2小时才调出来呢?快和小编一起看看吧. Sb题:指除了sbwzx别人都能做出来的题 1.CE:震惊!sbwzx竟然连map都不会用, ...

  8. allegro查看线宽的方法

  9. 嵌入式单片机之stm32串口你懂了多少!!

    stm32作为现在嵌入式物联网单片机行业中经常要用多的技术,相信大家都有所接触,今天这篇就给大家详细的分析下有关于stm32的出口,还不是很清楚的朋友要注意看看了哦,在最后还会为大家分享有些关于stm ...

  10. Shell脚本学习笔记之(自动填充函数模板)

    其实,vii 就是写的一个脚本,跟 vi 没半毛钱关系,只不过借用一下这个名字而已.那这个脚本长什么样呢?look: 下面来详细的解析上面的代码,来看第1行: #!/bin/bash 这是Shell脚 ...