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.
Called by new? Bind to the newly created object.
Called by call or apply (or bind)? Binds to the specified object.
Called by the context object? Bind to that context object.
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!