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


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


面向百度編程

公眾號

weixinQRcode.png

往期文章

個人主頁


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM