当前位置:网站首页>Use js to simply implement the apply, call and bind methods
Use js to simply implement the apply, call and bind methods
2022-06-25 05:00:00 【MomentYY】
Use JS It's a simple implementation apply、call and bind Method
Catalog
1. Methods to introduce
apply、call and bind Are built-in methods provided by the system , Each function can use these three methods , Because apply、call and bind It's all here Function On the prototype of (Function.prototype), And their role is to explicitly bind when we call functions this. Let's first introduce their basic usage :
apply Method : Call a with a given this The value of the function , And with a ** Array ( Or a class array object )** Parameters provided in the form of .
Use the syntax :
func.apply(thisArg, [argsArray])- thisArg: stay func Function call binding this value ;
- [argsArray]: An array or class array object , The array elements will be passed as separate parameters to the func function ;
Use effect :
function foo(x, y ,z) { console.log(this, x, y, z) } const obj = { name: 'curry', age: 30 } /** * 1. take obj Object is bound to foo Functional this * 2. Array 1 2 3 Respectively passed to foo The three parameters corresponding to the function */ foo.apply(obj, [1, 2, 3])
call Method : Use a specified this Values and given separately One or more parameters To call a function .
Use the syntax :
func.call(thisArg, arg1, arg2, ...)- thisArg: stay func Function call binding this value ;
- arg1, arg2, …: List of specified parameters , Pass as a parameter to func function ;
Use effect :
function foo(x, y ,z) { console.log(this, x, y, z) } const obj = { name: 'curry', age: 30 } /** * 1. take obj Object is bound to foo Functional this * 2.call Of the remaining parameters a b c Respectively passed to foo The three parameters corresponding to the function */ foo.call(obj, 'a', 'b', 'c')
bind Method : Create a new function , stay bind() When called , Of this new function this Is specified as bind() The first parameter of , The rest of the parameters will be the parameters of the new function , For calling .
Use the syntax :
func.bind(thisArg[, arg1[, arg2[, ...]]])- thisArg: call func Function as this The value passed by the parameter to the objective function ;
- arg1, arg2, …: When the target function is called , Preset in func Parameters in the parameter list of the function ;
Use effect :
function foo(...args) { console.log(this, ...args) } const obj = { name: 'curry', age: 30 } /** * 1. take obj Object is bound to foo Functional this * 2.bind Of the remaining parameters 1 2 3 Respectively passed to foo Parameters in function * 3. Also available at newFoo Pass in parameters when calling , At this time bind The parameters passed will be the same as newFoo The parameters passed during the call to merge */ const newFoo = foo.bind(obj, 1, 2, 3) newFoo() newFoo('a', 'b', 'c')
summary :
- apply and call It is mainly used to give a function when calling a function this The value corresponding to the binding , The two functions are similar , The main difference is that except for the first parameter ,apply Method accepts an array of arguments , and call Method accepts a list of arguments .
- bind It's also to assign... To a function this Bound value , differ apply and call Yes. , It returns a new function , In the new function this The point is the value we specify , And the parameters passed in separately will be merged .
2.apply、call and bind Method implementation
In order that all defined functions can use our custom apply、call and bind Method , Therefore, you need to hang your own implementation method on Function On the prototype of , In this way, all functions can find the custom three methods through the prototype chain .
2.1.apply The implementation of the
Function.prototype.myApply = function(thisArg, argArray) {
// 1. Get the function that needs to be executed at present
// because myApply It needs to be called by the current function , according to this Implicit binding of , Here this It refers to the function that needs to be executed at present
const fn = this
// 2. The incoming thisArg Make boundary judgment
if (thisArg === null || thisArg === undefined) {
// When it comes to null perhaps undefined yes , Of the function being executed this Point directly to the global window
thisArg = window
} else {
// Will the incoming thisArg Objectification , Convenient back in thisArg Add attribute
thisArg = Object(thisArg)
}
// It can also be simply written as a ternary operator :
// thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)
// 3. To obtain the fn Add to thisArg On the object
// Use here Symbol The reason is to avoid external incoming thisArg Properties in and add fn There are conflicts
const fnSymbol = Symbol()
Object.defineProperty(thisArg, fnSymbol, {
enumerable: false,
configurable: true,
writable: false,
value: fn
})
// It can also be simply written as
// thisArg[fnSymbol] = fn
// 4. Yes argArray Judge
// See if there is an incoming value , If no value is passed in, it defaults to []
argArray = argArray || []
// 5. Call to get fn function , And expand the corresponding incoming array and pass it to the past
const result = thisArg[fnSymbol](...argArray)
// Delete the added attribute after calling
delete thisArg[fnSymbol]
// 6. Return the result
return result
}
test : Although the printed object still exists Symbol attribute , In fact, it has passed delete Deleted , Here is the problem of object reference .
function foo(x, y, z) {
console.log(this, x, y, z)
}
foo.myApply({
name: 'curry'}, [1, 2, 3])

2.2.call The implementation of the
call Method implementation and apply The implementation of the method is almost , It mainly lies in the processing of the following parameters .
Function.prototype.myCall = function(thisArg, ...args) {
// 1. Get the function that needs to be executed at present
const fn = this
// 2. The incoming thisArg Make boundary judgment
thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)
// 3. To obtain the fn Add to thisArg On the object
const fnSymbol = Symbol()
thisArg[fnSymbol] = fn
// 4. Call to get fn function , And will correspond to the incoming args Pass on the past
const result = thisArg[fnSymbol](...args)
// Delete the added attribute after calling
delete thisArg[fnSymbol]
// 5. Return the result
return result
}
test :
function foo(x, y, z) {
console.log(this, x, y, z)
}
foo.myCall({
name: 'curry'}, 1, 2, 3)

2.3.bind The implementation of the
bind The implementation of the method is a little more complex , The problem of parameter merging needs to be considered .
Function.prototype.myBind = function(thisArg, ...argsArray) {
// 1. Get the current objective function , That is, the current use myBind Function of method
const fn = this
// 2. The incoming thisArg Make boundary judgment
thisArg = (thisArg === null || thisArg === undefined) ? window : Object(thisArg)
// 3. To obtain the fn Add to thisArg On the object
const fnSymbol = Symbol()
thisArg[fnSymbol] = fn
// 4. Define a new function
function newFn(...args) {
// 4.1. Merge myBind and newFn Incoming parameter
const allArgs = [...argsArray, ...args]
// 4.2. Call the function that really needs to be called , And pass the merged parameters to
const result = thisArg[fnSymbol](...allArgs)
// 4.3. Delete the added attribute after calling
delete thisArg[fnSymbol]
// 4.4. Return the result
return result
}
// 6. Return the new function to
return newFn
}
test :
function foo(x, y, z) {
console.log(this, x, y, z)
}
const newFoo = foo.myBind({
name: 'curry' }, 1, 2)
newFoo(3)

边栏推荐
- Database query optimization method
- Upgrade PHP to php7 X (III) failure of wechat payment callback
- Fun CMD command line~
- Eyeshot Ultimate 2022 Crack By Xacker
- Why does the SQL statement hit the index faster than it does not?
- Triangle class (construction and deconstruction)
- 《QDebug 2022年6月》
- SQL lab range explanation
- ORA-00800: soft external error
- ThinkPHP 5 log management
猜你喜欢

Kotlin Compose 完善toDo项目 Surface 渲染背景 与阴影

Summary of SQL injection (I)

The construction and usage of wampserver framework

2021-03-23

渗透测试-目录遍历漏洞

两小时带你进入软件测试行业风口(附全套软件测试学习路线)

Teach you to write non maintainable PHP code step by step

Chapter IX app project test (2) test tools

魔法猪系统重装大师怎么使用

How to use the Magic pig system reinstallation master
随机推荐
渗透测试-目录遍历漏洞
Precise delay based on Cortex-M3 and M4 (systick delay of system timer can be used for STM32, aducm4050, etc.)
Upgrade PHP to php7 The impact of X (2), the obsolescence of mcrypt decryption
Customize the console plot result style
API interface management setup -eolinker4.0
WPF uses Maui's self drawing logic
OLAP analysis engine kylin4.0
WPF 使用 MAUI 的自绘制逻辑
ASEMI三相整流桥的工作原理
ASEMI大功率场效应管和三极管的区别
Sleep more, you can lose weight. According to the latest research from the University of Chicago, sleeping more than 1 hour a day is equivalent to eating less than one fried chicken leg
How do the defi protocols perform under this round of stress test?
Mobile number regular expression input box loses focus verification
ORA-00800: soft external error
EL & JSTL (XIII)
Basic knowledge of web pages (URL related)
Web3 DApp用户体验最佳实践
ThinkPHP 5 log management
Method of opening data recovery of solid state disk
Teach you to write non maintainable PHP code step by step