Summary of the four binding rules for this in JavaScript, javascriptthis
Preface
If you want to ask which two knowledge points in javascript are confusing, the scope query andthis
The Mechanism is definitely at the top. So this article will introduce javascriptthis
For more information, see the following.
Binding rules
1. default binding
When an independent function is called,this
Point to a global object. If strict mode is used, the global object cannot be bound by default,this
Bindundefined
.
function foo() { console.log(this.a);}var a = 2;foo(); // 2
Strict mode:
function foo() { "use strict"; console,log(this.a);}var a = 2;foo(); // TypeError: this is undefined
2. Implicit binding
When a function references a context object (that is, a function is added to an object as a reference property), the implicit binding rule addsthis
Bind to the context object.
function foo() { console.log( this.a);}var obj = { a: 2, foo: foo};obj.foo(); // 2
Only the top or last layer of the Object Property Reference chain will affect the call location:
Obj1.obj2. foo (); // this in foo is bound to obj2.
2.1 implicit loss
Implicit loss refers to the loss of the binding object in the function, that is, it will apply the default binding rules of 1st, so asthis
Bind to a global object orundefined
Depends on whether it is running in strict mode. Implicit loss occurs in the following situations:
The function bound to the context object is assigned to a new function and then called:
Function foo () {console. log (this. a);} var obj = {a: 2, foo: foo}; var bar = obj. foo; // function alias var a = "this is a global variable"; bar (); // "this is a global variable"
When the callback function is passed in:
Function foo () {console. log (this. a);} function doFoo (fn) {fn (); // <-- call location} var obj = {a: 2, foo: foo }; var a = "this is a global variable"; doFoo (obj. foo); // "this is a global variable"
In fact, this is a variant of the first case. In fact, parameter passing is an implicit value assignment. In addition to developer-defined functions, built-in functions suchsetTimeout
The implicit loss also occurs.
3. Explicit binding
The core of explicit binding is the built-in JavaScriptcall(..)
Andapply(..)
These two methods can be used in the vast majority of functions provided by JavaScript and all the functions created by the developer.
call(..)
Andapply(..)
The first parameter of is an object (the difference between the two is in the form of parameters passed in later, which is not the focus here, not discussed). They will bind this to this object. Because you can directly specifythis
The bound object. Therefore, this rule is called explicit binding.
function foo() { console.log( this.a);}var obj = { a: 2};foo.call(obj); // 2
If the first parameter passed in by call or apply is the original value (string type, boolean type, or numeric type), the original value will be converted to its object form (new String()
,new Boolean()
Ornew Number()
".
Explicit binding still cannot solve the problem of missing binding.
3.1 hard binding
As a variant of explicit binding, hard binding can solve the problem of losing binding.
Function foo () {console. log (this. a);} var obj = {a: 2}; var bar = function () {foo. call (obj) ;}; bar (); // 2 setTimeout (bar, 100); // 2bar. call (window); // invalid. The hard-bound bar will not modify its this
Force binding within a new functionthis
To an object, no matter how the new function is called later, itsthis
Will not be lost.
A typical application scenario is to create a function package, input all parameters, and return all received values:
function foo(something) { console.log(this.a, something); return this.a + something;}var obj = { a:2};var bar = function() { return foo.call(obj, arguments);};var b = bar(3); // 2 3console.log(b); // 5
You can also change the bound object to a configurable one to form an auxiliary binding function:
...function bind(fn, obj){ return function(){ return fn.apply(obj, arguments); };}...
Since hard binding is too common, ES5 provides built-inFunction.prototype.bind
The usage is as follows:
function foo(something) { console.log(this.a, something); return this.a + something;}var obj = { a: 2};var bar = foo.bind(obj);var b = bar(3); // 2 3console.log(b); // 5
3.2 "context" of API calls"
JavaScript itself and many third-party library functions provide an optional parameter, which is usually called "context ". bind(..)
Make sure that the callback function uses the specifiedthis
.
Function foo (el) {console. log (el, this. id);} var obj = {id: "awsome"}; // call foo (..) bind this to obj [1, 2, 3]. forEach (foo, obj); // 1 awsome 2 awsome 3 awsome
Actually, these functions are still called.call()
Orapply()
In this way, developers need to write less code.
4. new binding
Usenew
When you call a function, the following operations are automatically performed:
1. Create a new object
2. The new object will be connected by a [prototype ].
3. This new object will be bound to the function callthis
4. If the function does not return other objectsnew
The function call in the expression automatically returns the new object.
Example:
function foo() { this.a = a;}var bar = new foo(2);console.log(bar.a); // 2
Usenew
To callfoo(..)
Creates a new object and binds itfoo(..)
In the callthis
.
Priority
The specific inference details are not described. The usage of the above four binding rules is inferred as follows:
1. Whether the function is innew
Call (new
Bound )? If yesthis
It is bound to a newly created object.
var bar = new foo();
2. Whether the function passescall
,apply
(Show binding) or hard binding? If yes,this
The specified object is bound.
var bar = foo.call(obj2);
3. is a function called in a context object (implicitly bound )? If yes,this
The context object to bind.
var bar = obj1.foo();
4. If none of them are, use the default binding. In strict modeundefined
Otherwise, it is bound to a global object.
var bar = foo();
Binding exceptions
Ifnull
Orundefined
Asthis
Bind objectcall
,apply
Orbind
These values are ignored during the call, and the default binding rules are applied. (It is recommended that you use an empty object to bind this in the book ).
Indirect reference. This situation may easily occur when values are assigned:
function foo() { console.log( this.a);}var a = 2;var o = {a: 3, foo: foo};var p = {a: 4};o.foo(); // 3(p.foo = o.foo)(); // 2
p.foo()
Actually referencedfoo()
In this case, the application is bound by default.
ES6 changesthis
The chaotic binding of the corresponding efforts, the birth of the arrow function, which is determined according to the current lexical Scopethis
Instead of the preceding four rules, the arrow function inheritsthis
Binding (this is actually in the code before ES6self = this
Is a truth ).
Summary
The above is all about this article. I hope it will help you in your study or work. If you have any questions, please leave a message.