Summary of the four binding rules for this in JavaScript, javascriptthis

Source: Internet
Author: User

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 andthisThe Mechanism is definitely at the top. So this article will introduce javascriptthisFor 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,thisBindundefined.

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.bindThe 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 modeundefinedOtherwise, it is bound to a global object.

var bar = foo();

Binding exceptions

Ifnull Orundefined Asthis Bind objectcall,apply OrbindThese 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 = thisIs 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.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.