资讯专栏INFORMATION COLUMN

JS中bind、call和apply的作用以及在TS装饰器中的用法

happyfish / 3550人阅读

摘要:目录,前言,,例子,直接调用,将指向另一个对象,传递参数,,例子,直接调用,将指向另一个对象,传递参数,合并数组,,例子,直接调用,将指向另一个对象,传递参数,中装饰器使用,总结,相同点,不同点,前言,前言和在函数式编程时候非常有用,本

 

目录
  • 1,前言
  • 1,call
    • 1.1,例子
    • 1.2,直接调用
    • 1.3,将this指向另一个对象
    • 1.4,传递参数
  • 2,apply
    • 2.1,例子
    • 2.2,直接调用
    • 2.3,将this指向另一个对象
    • 2.4,传递参数
    • 2.5,合并数组
  • 3,bind
    • 3.1,例子
    • 3.2,直接调用
    • 3.3,将this指向另一个对象
    • 3.4,传递参数
  • 4,TypeScript中装饰器使用
  • 5,总结
    • 5.1,相同点
    • 5.2,不同点

 

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


公众号

往期文章

  • 助你上手Vue3全家桶之Vue-Router4教程
  • 助你上手Vue3全家桶之Vue3教程
  • 助你上手Vue3全家桶之VueX4教程
  • 使用nvm管理node.js版本以及更换npm淘宝镜像源
  • 超详细!Vue-Router手把手教程
  • vue中利用.env文件存储全局环境变量,以及配置vue启动和打包命令
  • 微信小程序实现搜索关键词高亮
  • 超详细!Vue的九种通信方式
  • 超详细!Vuex手把手教程

个人主页

  • CSDN
  • GitHub
  • 简书
  • 博客园
  • 掘金
接受失败,但不选择放弃!
 

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/124137.html

相关文章

  • 前端_JavaScript_面向对象编程

    摘要:面向对象编程对象的原生方法分成两类自身的方法静态方法和的实例方法。的静态方法方法与,参数是对象,返回一个数组,数组的值是改对象自身的所有属性名区别在于返回可枚举的属性,返回不可枚举的属性值。 面向对象编程 Objects对象的原生方法分成两类:Object自身的方法(静态方法)和Object的实例方法。注意Object是JavaScript的原生对象,所有的其他对象都是继承自Objec...

    Blackjun 评论0 收藏0
  • Python装饰器高级用法

    摘要:在中,装饰器一般用来修饰函数,实现公共功能,达到代码复用的目的。智能装饰器上节介绍的写法,嵌套层次较多,如果每个类似的装饰器都用这种方法实现,还是比较费劲的脑子不够用,也比较容易出错。假设有一个智能装饰器,修饰装饰器,便可获得同样的能力。 在Python中,装饰器一般用来修饰函数,实现公共功能,达到代码复用的目的。在函数定义前加上@xxxx,然后函数就注入了某些行为,很神奇!然而,这只...

    AlphaWallet 评论0 收藏0
  • 魔幻语言 JavaScript 系列之 callbind 以及上下文

    摘要:那么,它到底是如何工作的呢让我们从一种更简单的实现开始实际上这种实现代码更短,并且更易读是函数原型中的一个函数,它调用函数,使用第一个参数作为参数,并传递剩余参数作为被调用函数的参数。 原文:The Most Clever Line of JavaScript 作者:Seva Zaikov 原文 最近 一个朋友 发给我一段非常有趣的 JavaScript 代码,是他在某个 开源库中...

    cuieney 评论0 收藏0
  • 理解 JavaScript call()/apply()/bind()

    摘要:理解文章中已经比较全面的分析了在中的指向问题,用一句话来总结就是的指向一定是在执行时决定的,指向被调用函数的对象。与和直接执行原函数不同的是,返回的是一个新函数。这个新函数包裹了原函数,并且绑定了的指向为传入的。 理解 JavaScript this 文章中已经比较全面的分析了 this 在 JavaScript 中的指向问题,用一句话来总结就是:this 的指向一定是在执行时决定的,...

    duan199226 评论0 收藏0
  • TS装饰者模式(Decorator)

    摘要:装饰者模式装饰者模式就是动态的给类或对象增加功能的设计模式。下的实现里的装饰器目前处在建议征集的第二阶段,不被浏览器所支持,如果想要提前使用这个新特性就需要,等工具进行转译。这里介绍下的用法。 1.1、装饰者模式 装饰者模式就是动态的给类或对象增加功能的设计模式。在程序运行时动态的给一个具备基础功能的类或对象添加新的功能,并且不会改变会破坏基础类和对象的功能。先提炼出产品的最小可用产品...

    SolomonXie 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<