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手把手教程
個人主頁