Get the solution ↓↓↓
thisthis (aka "the context") is a special keyword inside each function and its value only depends on how the function was called, not how/when/where it was defined. It is not affected by lexical scopes like other variables (except for arrow functions, see below). Here are some examples:
function foo() {
console.log(this);
}
// normal function call
foo(); // `this` will refer to `window`
// as object method
var obj = {bar: foo};
obj.bar(); // `this` will refer to `obj`
// as constructor function
new foo(); // `this` will refer to an object that inherits from `foo.prototype`
To learn more aboutthis, have a look at the MDN documentation.
thisECMAScript 6 introduced arrow functions, which can be thought of as lambda functions. They don't have their ownthis binding. Instead,this is looked up in scope just like a normal variable. That means you don't have to call.bind. That's not the only special behavior they have, please refer to the MDN documentation for more information.
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => alert(this.data));
}
thisYou actually don't want to accessthis in particular, but the object it refers to. That's why an easy solution is to simply create a new variable that also refers to that object. The variable can have any name, but common ones areself andthat.
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function() {
alert(self.data);
});
}
Sinceself is a normal variable, it obeys lexical scope rules and is accessible inside the callback. This also has the advantage that you can access thethis value of the callback itself.
this of the callback - part 1It might look like you have no control over the value ofthis because its value is set automatically, but that is actually not the case.
Every function has the method , which returns a new function withthis bound to a value. The function has exactly the same behavior as the one you called.bind on, only thatthis was set by you. No matter how or when that function is called,this will always refer to the passed value.
function MyConstructor(data, transport) {
this.data = data;
var boundFunction = (function() { // parenthesis are not necessary
alert(this.data); // but might improve readability
}).bind(this); // <- here we are calling `.bind()`
transport.on('data', boundFunction);
}
In this case, we are binding the callback'sthis to the value ofMyConstructor'sthis.
Note: When a binding context for jQuery, use instead. The reason to do this is so that you don't need to store the reference to the function when unbinding an event callback. jQuery handles that internally.
this of the callback - part 2Some functions/methods which accept callbacks also accept a value to which the callback'sthis should refer to. This is basically the same as binding it yourself, but the function/method does it for you. is such a method. Its signature is:
array.map(callback[, thisArg])
The first argument is the callback and the second argument is the valuethis should refer to. Here is a contrived example:
var arr = [1, 2, 3];
var obj = {multiplier: 42};
var new_arr = arr.map(function(v) {
return v * this.multiplier;
}, obj); // <- here we are passing `obj` as second argument
Note: Whether or not you can pass a value forthis is usually mentioned in the documentation of that function/method. For example, jQuery's describes an option calledcontext:
This object will be made the context of all Ajax-related callbacks.
Another common manifestation of this problem is when an object method is used as callback/event handler. Functions are first-class citizens in JavaScript and the term "method" is just a colloquial term for a function that is a value of an object property. But that function doesn't have a specific link to its "containing" object.
Consider the following example:
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = function() {
console.log(this.data);
};
The functionthis.method is assigned as click event handler, but if thedocument.body is clicked, the value logged will beundefined, because inside the event handler,this refers to thedocument.body, not the instance ofFoo.
As already mentioned at the beginning, whatthis refers to depends on how the function is called, not how it is defined.
If the code was like the following, it might be more obvious that the function doesn't have an implicit reference to the object:
function method() {
console.log(this.data);
}
function Foo() {
this.data = 42,
document.body.onclick = this.method;
}
Foo.prototype.method = method;
The solution is the same as mentioned above: If available, use.bind to explicitly bindthis to a specific value
document.body.onclick = this.method.bind(this);
or explicitly call the function as a "method" of the object, by using an anonymous function as callback / event handler and assign the object (this) to another variable:
var self = this;
document.body.onclick = function() {
self.method();
};
or use an arrow function:
document.body.onclick = () => this.method();
bind() function.bind() functionfunction MyConstructor(data, transport) {
this.data = data;
transport.on('data', ( function () {
alert(this.data);
}).bind(this) );
}
// Mock transport object
var transport = {
on: function(event, callback) {
setTimeout(callback, 1000);
}
};
// called as
var obj = new MyConstructor('foo', transport);
If you are using Underscore.js - http://underscorejs.org/#bind
transport.on('data', _.bind(function () {
alert(this.data);
}, this));
function MyConstructor(data, transport) {
var self = this;
this.data = data;
transport.on('data', function() {
alert(self.data);
});
}
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => {
alert(this.data);
});
}
It's all in the "magic" syntax of calling a method:
object.property();
When you get the property from the object and call it in one go, the object will be the context for the method. If you call the same method, but in separate steps, the context is the global scope (window) instead:
var f = object.property;
f();
When you get the reference of a method, it's no longer attached to the object. It's just a reference to a plain function. The same happens when you get the reference to use as a callback:
this.saveNextLevelData(this.setAll);
That's where you would bind the context to the function:
this.saveNextLevelData(this.setAll.bind(this));
If you are using jQuery you should use the$.proxy method instead, asbind is not supported in all browsers:
this.saveNextLevelData($.proxy(this.setAll, this));
You should know about "this" Keyword.
As per my view you can implement "this" in three ways (Self|Arrow function|Bind Method)
A function'sthis keyword behaves a little differently in JavaScript compared to other languages.
It also has some differences between strict mode and non-strict mode.
In most cases, the value of this is determined by how a function is called.
It can't be set by assignment during execution, and it may be different each time the function is called.
ES5 introduced the bind() method to set the value of a function'sthis regardless of how it's called,
And ES2015 introduced arrow functions that don't provide their ownthis binding (it retains this value of the enclosing lexical context).
Method1: Self - Self is being used to maintain a reference to the original this even as the context is changing. It's a technique often used in event handlers (especially in closures).
Reference: this
function MyConstructor(data, transport) {
this.data = data;
var self = this;
transport.on('data', function () {
alert(self.data);
});
}
Method2: Arrow function - An arrow function expression is a syntactically compact alternative to a regular function expression, although without its own bindings to the this, arguments, super, or new.target keywords.
Arrow function expressions are ill-suited as methods, and they cannot be used as constructors.
Reference: Arrow function expressions
function MyConstructor(data, transport) {
this.data = data;
transport.on('data',()=> {
alert(this.data);
});
}
Method 3: Bind - The bind() method creates a new function that, when called, has itsthis keyword set to the provided value with a given sequence of arguments preceding any provided when the new function is called.
Reference: Function.prototype.bind()
function MyConstructor(data, transport) {
this.data = data;
transport.on('data',(function() {
alert(this.data);
}).bind(this);
The term "context" is sometimes used to refer to the object referenced by this. Its use is inappropriate, because it doesn't fit either semantically or technically with ECMAScript's .
"Context" means the circumstances surrounding something that adds meaning, or some preceding and following information that gives extra meaning. The term "context" is used in ECMAScript to refer to , which is all the parameters, scope, and this within the scope of some executing code.
This is shown in ECMA-262 section 10.4.2:
Set the ThisBinding to the same value as the ThisBinding of the calling execution context
Which clearly indicates that this is part of an execution context.
An execution context provides the surrounding information that adds meaning to the code that is being executed. It includes much more information than just the .
The value of this isn't "context". It's just one part of an execution context. It's essentially a local variable that can be set by the call to any object and in strict mode, to any value at all.
First, you need to have a clear understanding of and behaviour of the {-code-2} keyword in the context of .
{-code-2} &:
There are two types of in JavaScript. They are:
Global Scope
Function Scope
In short, global refers to the window object. Variables declared in a global are accessible from anywhere.
On the other hand, function resides inside of a function. A variable declared inside a function cannot be accessed from the outside world normally.
The {-code-2} keyword in the global refers to the window object. {-code-2} inside a function also refers to the window object. So {-code-2} will always refer to the window until we find a way to manipulate {-code-2} to indicate a context of our own choosing.
Different ways to manipulatethis inside {-code-31}back functions:
Here I have a constructor function {-code-31}ed Person. It has a property {-code-31}ed {-code-12} and four method {-code-31}ed {-code-13}, {-code-14}, {-code-15}, and {-code-16}. All four of them has one specific task. Accept a {-code-31}back and invoke it. The {-code-31}back has a specific task which is to log the {-code-12} property of an instance of Person constructor function.
function Person({-code-12}){
this.{-code-12} = {-code-12}
this.{-code-13} = function({-code-31}back){
{-code-31}back.bind(this)()
}
this.{-code-14} = function({-code-31}back){
{-code-31}back()
}
this.{-code-15} = function({-code-31}back){
{-code-31}back.{-code-31}(this)
}
this.{-code-16} = function({-code-31}back){
{-code-31}back.{-code-40}(this)
}
}
function {-code-19}(){
// Function to be used as {-code-31}back
var parentObject = this
console.log(parentObject)
}
Now let's create an instance from {-code-21} constructor and invoke different versions of {-code-18} (X refers to 1,2,3,4) method with {-code-19} to see how many ways we can manipulate the this inside {-code-31}back to refer to the {-code-21} instance.
{-code-22}
What bind do is to create a new function with the this keyword set to the provided value.
{-code-13} and{-code-14} use bind to manipulate this of the {-code-31}back function.
this.{-code-13} = function({-code-31}back){
{-code-31}back.bind(this)()
}
this.{-code-14} = function({-code-31}back){
{-code-31}back()
}
The first one binds this with a {-code-31}back inside the method itself. And for the second one, the {-code-31}back is passed with the object bound to it.
p1.{-code-13}({-code-19}) // pass simply the {-code-31}back and bind happens inside the {-code-13} method
p1.{-code-14}({-code-19}.bind(p1)) // uses bind before passing {-code-31}back
The {-code-30} of the {-code-31} method is used as this inside the function that is invoked with {-code-31} attached to it.
{-code-15} uses {-code-31} to manipulate the this to refer to the {-code-21} object that we created, instead of the window object.
this.{-code-15} = function({-code-31}back){
{-code-31}back.{-code-31}(this)
}
And it is {-code-31}ed like the following:
p1.{-code-15}({-code-19})
Similar to {-code-31}, the {-code-30} of {-code-40} refers to the object that will be indicated by the this keyword.
{-code-16} uses {-code-40} to manipulate this to refer to a {-code-21} object
this.{-code-16} = function({-code-31}back){
{-code-31}back.{-code-40}(this)
}
And it is {-code-31}ed like the following. Simply the {-code-31}back is passed,
p1.{-code-16}({-code-19})
We can not bind this tosetTimeout(), as it always executes with the global object (Window). If you want to access thethis context in the callback function then by usingbind() to the callback function, we can achieve it as:
setTimeout(function(){
this.methodName();
}.bind(this), 2000);
The question revolves around how thethis keyword behaves in JavaScript.this behaves differently as below,
this is usually determined by a function execution context.this refers to the global object (thewindow object).this will beundefined as in strict mode, global object refers toundefined in place of thewindow object.this keyword will be bound to.call(),bind(), andapply()new keyword is used (a constructor), this is bound to the new object being created.this — instead,this is bound lexically (i.e., based on the original context)As most of the answers suggest, we can use the arrow function orbind() Method or Self var. I would quote a point about lambdas (arrow function) from Google JavaScript Style Guide
Prefer using arrow functions over f.bind(this), and especially over goog.bind(f, this). Avoid writing const self = this. Arrow functions are particularly useful for callbacks, which sometimes pass unexpectedly additional arguments.
Google clearly recommends using lambdas rather than bind orconst self = this
So the best solution would be to use lambdas as below,
function MyConstructor(data, transport) {
this.data = data;
transport.on('data', () => {
alert(this.data);
});
}
References:
Currently there is another approach possible if classes are used in code.
With support of class fields, it's possible to make it the following way:
class someView {
onSomeInputKeyUp = (event) => {
console.log(this); // This refers to the correct value
// ....
someInitMethod() {
//...
someInput.addEventListener('input', this.onSomeInputKeyUp)
For sure under the hood it's all the old good arrow function that binds context, but in this form it looks much more clear that explicit binding.
Since it's a Stage 3 Proposal, you will need Babel and appropriate Babel plugin to process it as for now (08/2018).
Another approach, which is the standard way since DOM2 to bindthis within the event listener, that let you always remove the listener (among other benefits), is thehandleEvent(evt) method from theEventListener interface:
var obj = {
handleEvent(e) {
// always true
console.log(this === obj);
}
};
document.body.addEventListener('click', obj);
Detailed information about usinghandleEvent can be found here: DOM handleEvent: a cross-platform standard since year 2000
I was facing a problem withNgx line chartxAxisTickFormatting function which was called from HTML like this:[xAxisTickFormatting]="xFormat".
I was unable to access my component's variable from the function declared. This solution helped me to resolve the issue to find the correct this.
Instead of using the function like this:
xFormat (value): string {
return value.toString() + this.oneComponentVariable; //gives wrong result
}
Use this:
xFormat = (value) => {
// console.log(this);
// now you have access to your component variables
return value + this.oneComponentVariable
}
Some other people have touched on how to use the .bind() method, but specifically here is how you can use it with .then() if anyone is having trouble getting them to work together:
someFunction()
.then(function(response) {
//'this' wasn't accessible here before but now it is
}.bind(this))
As mentioned in the comments, an alternative would be to use an arrow function that doesn't have its own 'this' value
someFunction()
.then((response)=>{
//'this' was always accessible here
})
this in JavaScript:The value ofthis in JavaScript is 100% determined by how a function is called, and not how it is defined. We can relatively easily find the value ofthis by the 'left of the dot rule':
this is the object left of the dot of the function which is calledthis inside a function is often the global object (global in Node.js andwindow in a browser). I wouldn't recommend using thethis keyword here because it is less explicit than using something likewindow!Function.prototype.bind() a function that can fix the value ofthis. These are exceptions of the rule, but they are really helpful to fix the value ofthis.module.exports.data = 'module data';
// This outside a function in node refers to module.exports object
console.log(this);
const obj1 = {
data: "obj1 data",
met1: function () {
console.log(this.data);
},
met2: () => {
console.log(this.data);
},
};
const obj2 = {
data: "obj2 data",
test1: function () {
console.log(this.data);
},
test2: function () {
console.log(this.data);
}.bind(obj1),
test3: obj1.met1,
test4: obj1.met2,
};
obj2.test1();
obj2.test2();
obj2.test3();
obj2.test4();
obj1.met1.call(obj2);
Output:
Let me walk you through the outputs one by one (ignoring the first log starting from the second):
this isobj2 because of the left of the dot rule, we can see howtest1 is calledobj2.test1();.obj2 is left of the dot and thus thethis value.obj2 is left of the dot,test2 is bound toobj1 via thebind() method. Thethis value isobj1.obj2 is left of the dot from the function which is called:obj2.test3(). Thereforeobj2 will be the value ofthis.obj2.test4()obj2 is left of the dot. However, arrow functions don't have their ownthis binding. Therefore it will bind to thethis value of the outer scope which is themodule.exports an object which was logged in the beginning.this by using thecall function. Here we can pass in the desiredthis value as an argument, which isobj2 in this case.You can use arrow function to avoid the issue with this .
const functionToTest = (dataToSet , transport) => {
this.dataToSet = dataToSet ;
transport.on('dataToSet ', () => {
console.log(this.dataToSet);
});
}
This is how I solved the problem
class myClass
{
constructor(parent)
{
this.callback = (function() {
this.callbackFunctionOfParent();
}).bind(parent);
}
callCallback() {
this.callback();
}
}
class Class2
{
constructor()
{
this.Name = "CLASS 2";
this.test = new myClass(this);
this.test.callCallback();
}
callbackFunctionOfParent()
{
console.log("parent is: " + this.Name);
}
}
var c2 = new Class2; Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Find the answer in similar questions on our website.
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.
PHP (from the English Hypertext Preprocessor - hypertext preprocessor) is a scripting programming language for developing web applications. Supported by most hosting providers, it is one of the most popular tools for creating dynamic websites.
The PHP scripting language has gained wide popularity due to its processing speed, simplicity, cross-platform, functionality and distribution of source codes under its own license.
https://www.php.net/
JavaScript is a multi-paradigm language that supports event-driven, functional, and mandatory (including object-oriented and prototype-based) programming types. Originally JavaScript was only used on the client side. JavaScript is now still used as a server-side programming language. To summarize, we can say that JavaScript is the language of the Internet.
https://www.javascript.com/
JQuery is arguably the most popular JavaScript library with so many features for modern development. JQuery is a fast and concise JavaScript library created by John Resig in 2006. It is a cross-platform JavaScript library designed to simplify client-side HTML scripting. Over 19 million websites are currently using jQuery! Companies like WordPress, Facebook, Google, IBM and many more rely on jQuery to provide a kind of web browsing experience.
https://jquery.com/
Node.js is an open source server-side framework built on top of the Google Chrome JavaScript Engine. The number of sites using NodeJS has increased by 84,000. It is one of the busiest cross-platform JavaScript runtimes. Node.js is an asynchronous, single-threaded, non-blocking I / O model that makes it lightweight and efficient. The Node.js package ecosystem, npm, is also the world's largest open source library ecosystem.
https://nodejs.org/
HTML (English "hyper text markup language" - hypertext markup language) is a special markup language that is used to create sites on the Internet.
Browsers understand html perfectly and can interpret it in an understandable way. In general, any page on the site is html-code, which the browser translates into a user-friendly form. By the way, the code of any page is available to everyone.
https://www.w3.org/html/
Welcome to the Q&A site for web developers. Here you can ask a question about the problem you are facing and get answers from other experts. We have created a user-friendly interface so that you can quickly and free of charge ask a question about a web programming problem. We also invite other experts to join our community and help other members who ask questions. In addition, you can use our search for questions with a solution.
Ask about the real problem you are facing. Describe in detail what you are doing and what you want to achieve.
Our goal is to create a strong community in which everyone will support each other. If you find a question and know the answer to it, help others with your knowledge.