Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to change the this direction of a function

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/01 Report--

This article introduces the relevant knowledge of "how to change the this direction of a function". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

If it is a function declaration, the this inside the function points to the global object or the object that called the function.

The this of the arrow function is bound to the this in the parent scope

Use call,apply,bind to bind this points to. Where bind permanently changes the direction of the this and will not be executed immediately. Apply,call temporarily changes the direction of the this and executes it immediately.

Apply,call differs in the parameter form of the call:

Call (thisArg, arg1?, arg2?, arg3?... The first argument represents the this point, and the remaining arguments are the arguments of the original function.

The first parameter of apply (thisArg, argArray?) represents the point of this, and the second parameter is passed as an array.

/ * example of bind, call, apply calls * /

Var obj = {

X: 'obj'

GetX: function () {

/ / Note that the arrow function cannot be used here.

Return this.x

}

}

/ / call the function property on the obj object, and this will be bound to obj.

/ / 'obj'

Console.log (obj.getX ())

Var x = 'window'

Function target (a, b, c) {

Console.log (a, b, c)

Return this.x

}

/ * bind * /

/ / undefined undefined undefined

/ / 'window'

Console.log (target ())

Const targetBound = target.bind (obj, 1); / / targetBound is a target that changes the direction of the this.

/ / 1 2 3

/ / 'obj'

Console.log (targetBound (2,3))

/ * call * /

/ / 4 5 6

/ / 'obj'

Console.log (target.call (obj, 4,5,6))

/ * apply * /

/ / 7 8 9

/ / 'obj'

Console.log (target.apply (obj, [7,8,9]))

Custom implementation call,apply,bind

These three functions all have strong error handling capabilities. If the incoming thisArg is a basic type, it will also be replaced by a wrapper class. Although it will not report an error, it is not recommended to write it. Try to pass complex types of variables as thisArg.

Custom implementation myBind,myCall,myApply

/ / first define a function that converts any type to an object, which is used to point to this

Function anyToObj (value) {

/ / symbol, bigint does not judge, directly in default

Switch (typeof value) {

Case 'boolean':

Return new Boolean (value)

Case 'number':

Return new Number (value)

Case 'string':

Return new String (value)

Case 'undefined':

Return this

Case 'object':

If (value = null) return this; / / the this here points to the global object

Return value

Default:

Return value

}

}

/ * myBind * /

Function.prototype.myBind = function (thisArg, … ArgArray) {

/ / prevent const myBind = Function.prototype.myBind; myBind ()

If (typeof this! = = 'function') {

Throw new TypeError ('myBind must be called on a function')

}

Const that = this; / / this points to the f of f.myBind ()

Const thatArg = anyToObj (thisArg); / / deal with thisArg

Const myBound = function (… Args) {

/ / specify a unique key

Const tempKey = Symbol ('_ _ innerFunction__')

ThatArg.tempKey = that; / / assign the that function to a property of an object

Let ret

If (this instanceof myBound) {

/ / myBound is returned after calling myBind. If you call new myBound (), you will enter this branch.

Ret = new thatArg.tempKey (… ArgArray.concat (args))

} else {

/ / here is a call to myBound (), so calling this in the tempKey method points to thatArg

Ret = thatArg.tempKey (… ArgArray.concat (args))

}

/ / it will not cause pollution to the object

Delete thatArg.tempKey

Return ret

}

Return myBound

}

/ * myCall * /

/ / compared with myBind, it calls directly

Function.prototype.myCall = function (thisArg, … ArgArray) {

If (typeof this! = = 'function') {

Throw new TypeError ('myCall must be called on a function')

}

Const thatArg = anyToObj (thisArg)

Const tempKey = Symbol ('_ _ innerFunction__')

ThatArg.tempKey = this

Const ret = thatArg.tempKey (… ArgArray)

Delete thatArg.tempKey

Return ret

}

/ * myApply * /

/ / compared with myCall, the second parameter is expected to be in the form of an array, with an extra CreateListFromArrayLike to convert argArray

Function.prototype.myApply = function (thisArg, argArray) {

If (typeof this! = = 'function') {

Throw new TypeError ('myApply must be called on a function')

}

Const CreateListFromArrayLike = function (val) {

/ / also lack of bigint processing, so put it directly in default.

Switch (typeof val) {

Case 'string':

Case 'number':

Case 'boolean':

Case 'symbol':

Throw new TypeError ('CreateListFromArrayLike called on non-object')

Case 'object':

If (Array.isArray (val)) return val

If (val = null) return []

Return Array.from (val)

Default:

Return []

}

}

/ / detect the type of argArray

Const tempArgArray = CreateListFromArrayLike (argArray)

Const thatArg = anyToObj (thisArg)

Const tempKey = Symbol ('_ _ innerFunction__')

ThatArg.tempKey = this

Const ret = thatArg.tempKey (… TempArgArray)

Delete thatArg.tempKey

Return ret

}

/ / so myBind,myCall,myApply is complete, so let's test it.

Var obj = {

X: 'obj'

GetX: function (a, b, c) {

Console.log (a, b, c)

Return this.x

}

}

Var x = 'window'

/ / 1 2 3

/ / 'obj'

Console.log (obj.getX (1,2,3))

/ / target becomes a global function, and this points to the global object

Const target = obj.getX

/ / 1 2 3

/ / 'window'

Console.log (target (1,2,3))

/ * myBind * /

Const targetBound = target.myBind (obj, 1)

/ / 1 2 3

/ / 'obj'

Console.log (targetBound (2,3))

/ * myCall * /

/ / 4 5 6

/ / 'obj'

Console.log (target.myCall (obj, 4,5,6))

/ * myApply * /

/ / 7 8 9

/ / 'obj'

Console.log (target.myApply (obj, [7,8,9]))

This is the end of "how to change the this direction of a function". Thank you for reading. If you want to know more about the industry, you can follow the website, the editor will output more high-quality practical articles for you!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report