Home  >  Article  >  Web Front-end  >  What is this in Javascript? 4 binding methods of this (introduction)

What is this in Javascript? 4 binding methods of this (introduction)

青灯夜游
青灯夜游Original
2018-09-21 17:19:222223browse

This chapter brings you what is this in Javascript? 4 binding methods of this (introduction). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.

What is this?

When a function is called, an activity record (sometimes called an execution context) is created. This record will contain information such as where the function was called (call stack), the calling method of the function, and the parameters passed in. this is one of the recorded attributes, which will be used during function execution.

This’s 4 binding methods

Default binding

function foo() { 
    console.log( this.a );
}
var a = 2;
foo(); // 2

This code Output 2, indicating that this is bound to the global object by default

Implicit binding

function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};
obj.foo(); // 2

This code binds this to the obj object. When the function references a context object (context), the implicit binding rule will bind this to this context object.

Implicit loss problem

// 例子1111
function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};
var bar = obj.foo; // 函数别名!

var a = "oops, global"; // a是全局对象的属性”

bar();  // "oops, global"
//2222
function foo() { 
    console.log( this.a );
}
var obj = { 
    a: 2,
    foo: foo 
};

var a = "oops, global"; // a是全局对象的属性

setTimeout( obj.foo, 100 ); // "oops, global

Example 1111 Although bar is a reference to obj.foo, in fact, it refers to the foo function itself, so at this time The bar() is actually a function call without any modifications, so the default binding is applied. Example 222 loses this binding in the setTimeout function. The principle is the same. We can regard parameter passing as an implicit assignment.

Explicit binding

When analyzing implicit binding, we must include a property pointing to the function inside an object, and Indirectly refer to the function through this attribute, thereby indirectly (implicitly) binding this to this object.

So what should we do if we don’t want to include a function reference inside the object, but want to force a function call on an object?

Those who have studied js are probably familiar with call, apply and bind. These native methods provided by js provide us with a way to explicitly bind this.

function foo() { 
    console.log( this.a );
}var obj = { 
    a:2};

foo.call( obj ); // 2

Through foo.call(..), we can force foo to bind its this to obj when calling it.

If you pass in a primitive value (string type, Boolean type, or numeric type) as the binding object of this, the primitive value will be converted into its object form (that is, new String (..), new Boolean(..) or new Number(..)). This is often called "boxing."

"From the perspective of this binding, call(..) and apply(..) are the same. Their differences are reflected in other parameters, but we don't need to consider these now."

Hard binding-bind implementation

We already know the 4 ways of binding this, but using call and apply we still cannot solve the problem of implicit loss , consider the following example:

function foo() { 
    console.log( this.a );
}

var obj = { 
    a:2
};

var bar = function() {
    foo.call( obj );
};

bar(); // 2
setTimeout( bar, 100 ); // 2

bar.call(windows) //无法再修改this

By calling, we forcefully specify foo's this in function bar. No matter how bar is called afterwards, it will always call foo manually on obj. This binding is a display Forced binding, hence the name hard binding. This is the origin of bind (because hard binding is more commonly used, and the bind method is new in es5). By formulating this through hard binding, the above code now becomes

...略var bar = foo.bind(obj)
bar(); // 2setTimeout( bar, 100 ); // 2

Binding rule priority And the new feature of this in es6

If you want to determine the this binding of a running function, you need to find the direct calling location of the function. Once found, the following four rules can be applied sequentially to determine the binding object of this.

  1. Called by new? Bind to the newly created object.

  2. Called by call or apply (or bind)? Binds to the specified object.

  3. Called by the context object? Bind to that context object.

  4. Default: bind to undefined in strict mode, otherwise bind to the global object.

A few small examples to understand this

unction showThis () {  console.log(this)
}function showStrictThis () {  'use strict'
  console.log(this)
}
showThis() // windowshowStrictThis() // undefined

The this object with the smallest priority is bound by default.

Think about the following example:

var person = {  name: '11',
  showThis () {    return this
  }
}

person.showThis() === person  //truevar person2 = { name: '22',
  showThis () {    return person.showThis()
  }
}var person3 = { name: '33',
  showThis () {    var retrunThis = person.showThis    return retrunThis()
  }
}

person.showThis()  //personperson2.showThis()  //?person3.showThis()  //?

We first need to find the calling location. In 2, there is the sentence return person.showThis(), which implicitly binds a person object, so person is output. , 3 is return retrunThis(), this is bound to the global by default, and returns window.

function showThis () {  
return this
}
var person = { name: 'person' }
showThis() // window
showThis.call(p1) // person
showThis.apply(p1) // person

The context object is specified through explicit binding.

function showThis () {
  return this
}
var person = { name: 'person' }

var personBind = showThis.bind(person)

personBind()   //person

var person2 = { name: 'person2' }

personBind.call(person2) //person

The bind method strongly binds this, and this can no longer be switched through explicit binding.

function showThis () {
  return this
}
var person = { name: 'person' }
var person2 = { name: 'person2' }

var personBind = showThis.bind(person)

personBind()    //person
new personBind()  //showThis

new has higher priority than bind, so this can be overridden.

function foo() { 
    setTimeout(() => {        
        // 这里的this在词法上继承自foo()
        console.log( this.a ); 
    },100);
}var obj = { 
    a:2};

foo.call( obj ); // 2

Arrow functions are not defined using the function keyword, but are defined using the operator => called "fat arrow". Arrow functions do not use the four standard rules of this, but determine this based on the outer (function or global) scope. Arrow function bindings cannot be modified, including new. There are many detailed and comprehensive explanations about arrow functions on the Internet. No more details here.

The above is the detailed content of What is this in Javascript? 4 binding methods of this (introduction). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn