This in JavaScript-notes

Source: Internet
Author: User

has been to the this point is very vague, find some other people's blog look, and re-read the "You do not know the JavaScript", the feeling is basically to understand, pick some of the key points of the record, some places for me to explain the book is not enough to write, so I do the next supplement to facilitate understanding, There is an understanding of the wrong place also hope to point out.

I. Clarification of misunderstandings

First you need to know:

1.this does not point to the function itself

The scope of the 2.this does not point to the lexical scope of the function in any case.

As an example:

function foo () {    var a = 2;      This . Bar ();} function Bar () {    Console.log (this. a);} Foo (); // referenceerror:a is not defined

The first time I saw this, I fell out of the hole, assuming that foo () in this point to the window, and bar () in the global can call bar (), but in fact it is wrong, you cannot use this to refer to a lexical scope inside of something.

This is the binding that occurs when a function is invoked, and what it points to depends entirely on where the function is called. There is nothing to do with the position of the function declaration, but to distinguish it from the scope of the function, the scope of the function is determined when it is defined.

To determine the this binding of a running function, you need to find the direct call location of the function.

Two. Call location

The call location is where the function is called in the code.

This has four binding rules:

1. Default binding: This in non-strict mode points to the global object, strict mode is bound to undefined. var bar = foo ()

2. Implicit binding: This points to the object that contains its function, so be aware of the implicit loss of the case. var bar = Obj1.foo ()

3. Show bindings: This points to the object specified by the call (), apply (), and bind () methods. var bar = Foo.call (OBJ2)

4.new binding: This points to a new object constructed. var bar = new Foo ()

Priority: New binding > Show Bindings > Implicit binding > Default Bindings

specifically see below:

1. Default Bindings

Default bindings are used by default when other rules cannot be applied. If the function is called independently, the default binding is used.

function foo () {
//See if the function body is in strict mode, look at this position ("use strict")
  Console.log (this. a);} var a = 2;  foo ();//2   only the Foo () function itself, which is called independently

In the above code, Foo () is invoked with a function reference without any adornments, so the default binding is used, and this is a pointer to the global object in non-strict mode, and strict mode is bound to undefined. Does not mean whether the call location is in strict mode, but whether the function body is in strict mode.

2. Implicit binding

Consider whether the function's call location has a context object, or whether it is owned or contained by an object.

function foo () {  Console.log (this. a);} var obj = {  2,  foo:foo  //foo () is added to obj as a reference property, at which point it is contained by the Obj object, and this points to obj} Obj.foo (); 2

Only the last layer in the object property reference chain affects the call location.

function foo () {  Console.log (this. a);} var obj2 = {    Foo:foo}var obj1 =  {2,  Obj2:obj2}obj1.obj2.foo ();  Although there are obj1 objects and Obj2 objects here, Obj2 is the last layer closest to Foo (), so it points to obj2

Implicit loss scenarios

Look at the following code:

function foo () {  Console.log (this. a);} var obj = {  2,  Foo:foo}var bar = Obj.foo;  Although bar is a reference to Obj.foo, actually bar refers only to the Foo function itself, which can be seen as bar () = foo (), at which time Foo () is called independently and binds to the global object var a = "oops, Global "; bar ();//oops, global  

There is also a common implicit loss scenario in which a callback function is passed in

function foo () {  Console.log (this. a);} function Dofoo (FN) {  fn ();} var obj = {  2,  Foo:foo}var a = "oops, global"//oops, Global  Obj.foo is actually implicitly assigned to FN as a parameter, and can be seen as FN = Obj.foo,
This time back to the case of the previous code, referring to the Foo function itself, as fn () = foo (), independent calls to the global object

3. Show Bindings

Use the call () and apply () methods of the function to use the display binding, the first parameter of both methods is an object, they will bind this object to this, specify this when the function is called, because you can specify the binding object is called the display binding.

function foo () {  Console.log (this. a);} var obj = {  2}foo.call (obj);

However, this display binding does not resolve the implicit loss problem, and you can use hard binding to resolve this problem.

function foo () {  Console.log (this. a);} var obj = {  2}varfunction() {  // 2  //2bar.call (window);//2

Created a function bar () and manually called Foo.call (obj) inside it, forcing the this of Foo to be bound to obj, and then, anyway, calling the function bar, it would always manually raise Foo on obj, which is called hard binding.

Hard binding is very common and ES5 provides a built-in method Function.prototype.bind,bind () returns a new hard-coded function that sets the parameter to the context of this and invokes the original function.

Two typical scenarios for hard binding:

    • Create a package function, pass in all the parameters and return all the values received
functionFoo (something) {Console.log ( This. A, something); return  This. A + something;//returns all THIS.A and something received}varobj ={A:2}varBar =function() {  returnfoo.apply (obj, arguments);//this points to obj,arguments for incoming parameter 3}varb = Bar (3);//2 3Console.log (b);//5
    • Create an auxiliary function that can be reused
functionfoo (something) {Console.log ( This. A, something); return  This. A +something;}functionbind (FN, obj) {return function() {    returnfn.apply (obj, arguments); };}varobj ={A:2}varBar =bind (foo, obj);varb = Bar (3); 2 3console.log (b); 5

4.new Bindings

Using new to invoke a function, or when a constructor call occurs, the following actions are performed:

① creates (constructs) a completely new object.

② this new object will be executed [[prototype]] connected.

③ this new object is bound to this of the function call.

④ If the function does not return another object, the function call in the new expression will automatically return the new object.

function Foo (a) {  this. A = A;}  var New foo (2); // call Foo () using the new operator, construct a new object bar and bind it to the This of Foo () // 2

Three. Binding exceptions

There are some exceptions to be aware of

1. Pass null or undefined as the binding object for this to call, apply, or bind.

Null and undefined are ignored when invoked, and then the default bindings are applied.

function foo () {  Console.log (this. a);} var a = 2; Foo.call (null); // 2

Sometimes you might choose NULL as a placeholder and choose NULL as the parameter, but always null to ignore this binding may have some side effects. A more secure approach is to pass in an empty non-commissioned object, and binding this to this object will not have any side effects on your program.

2. Inadvertently creates an "indirect reference" to a function

The default bindings are also applied, which is most likely to occur when assigning values.

function foo () {  Console.log (this. a);} var a = 2; var o = {  3,  Foo:foo}var p = {  4}o.foo (); // 3 (P.foo = O.foo); // 2 P.foo = The return value of O.foo is a reference to the target function, so the location of the call is Foo () and the default binding is applied

3. Soft binding softbind ()

Hard binding reduces the flexibility of the function, and it cannot be modified with an implicit binding or display binding after using hard binding.

Soft binding: Assigning a Global object and a value other than undefined to the default binding can implement the same effect as hard binding, while preserving the ability to implicitly bind or show the binding to modify this.

In addition to soft binding, the other principles of softbind () are similar to bind (). This is first checked at the time of invocation and if this is bound to a global object or undefined, the specified object is bound to this, otherwise this is not modified.

functionfoo () {Console.log ("Name:" + This. name);}varobj ={name:"Obj"}varObj2 ={name:"Obj2"}varObj3 ={name:"Obj3"}varFooobj =foo.softbind (obj); fooobj ();//objObj2.foo=foo.softbind (obj); Obj2.foo ();//obj2 Obj2.foo () is called, this is bound to obj2, not the global object or undefined, so the specified obj is not invoked, but the original obj2 is used instead. Fooobj.call (obj3);//bind obj3 with hard binding, no further modification aftersetTimeout (Obj2.foo,10);//hypothesissetTimeout (fn,10), FN actually refers to only Foo (), which can be seen as FN = Obj2.foo, similar to the previous implicit binding loss,
will use the default binding to global, a soft binding will occur, bound to the specified object, obj

4. Arrow functions

The arrow function cannot use the four binding rules in this, but rather determines this based on the outer (function or global) scope.

function foo () {  return (a) = {    Console.log (this. a);  }} var obj1 = {  2}var obj2 = {  3}var bar = Foo.call (obj1); Bar.call (OBJ2); // The 2 arrow function captures the This,foo () of Foo () when called, and this shows the binding to Obj1.
The This of bar (the reference arrow function) is also bound to obj1, and the binding of the arrow function cannot be modified

Arrow functions are commonly used in callback functions, such as event handlers or timers

function foo () {  = = {    Console.log (this. a);  the arrow function inherits the this binding of the outer function call, where the outer function of the arrow function is foo (), the This of Foo () is bound to obj, so the arrow function's This is also bound to obj.   }, (+);} var obj = {  2}foo.call (obj); // 2

This in JavaScript-notes

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.