1570159561
The this
keyword is a very important concept in JavaScript, and also a particularly confusing one to both new developers and those who have experience in other programming languages. In JavaScript, this
is a reference to an object. The object that this
refers to can vary, implicitly based on whether it is global, on an object, or in a constructor, and can also vary explicitly based on usage of the Function
prototype methods bind
, call
, and apply
.
Although this
is a bit of a complex topic, it is also one that appears as soon as you begin writing your first JavaScript programs. Whether you’re trying to access an element or event in the Document Object Model (DOM), building classes for writing in the object-oriented programming style, or using the properties and methods of regular objects, you will encounter this
.
In this article, you’ll learn what this
refers to implicitly based on context, and you’ll learn how to use the bind
, call
, and apply
methods to explicitly determine the value of this
.
There are four main contexts in which the value of this
can be implicitly inferred:
In the global context, this
refers to the global object. When you’re working in a browser, the global context is would be window
. When you’re working in Node.js, the global context is global
.
Note: If you are not yet familiar with the concept of scope in JavaScript, please review Understanding Variables, Scope, and Hoisting in JavaScript.
For the examples, you will practice the code in the browser’s Developer Tools console. Read How to Use the JavaScript Developer Console if you are not familiar with running JavaScript code in the browser.
If you log the value of this
without any other code, you will see what object this
refers to.
console.log(this)
OutputWindow {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
You can see that this
is window
, which is the global object of a browser.
In Understanding Variables, Scope, and Hoisting in JavaScript, you learned that functions have their own context for variables. You might be tempted to think that this
would follow the same rules inside a function, but it does not. A top-level function will still retain the this
reference of the global object.
You write a top-level function, or a function that is not associated with any object, like this:
function printThis() {
console.log(this)
}
printThis()
OutputWindow {postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, parent: Window, …}
Even within a function, this
still refers to the window
, or global object.
However, when using strict mode, the context of this
within a function on the global context will be undefined
.
'use strict'
function printThis() {
console.log(this)
}
printThis()
Outputundefined
Generally, it is safer to use strict mode to reduce the probability of this
having an unexpected scope. Rarely will someone want to refer to the window
object using this
.
For more information about strict mode and what changes it makes regarding mistakes and security, read the Strict mode documentation on MDN.
A method is a function on an object, or a task that an object can perform. A method uses this
to refer to the properties of the object.
const america = {
name: 'The United States of America',
yearFounded: 1776,
describe() {
console.log(`${this.name} was founded in ${this.yearFounded}.`)
},
}
america.describe()
Output"The United States of America was founded in 1776."
In this example, this
is the same as america
.
In a nested object, this
refers to the current object scope of the method. In the following example, this.symbol
within the details
object refers to details.symbol
.
const america = {
name: 'The United States of America',
yearFounded: 1776,
details: {
symbol: 'eagle',
currency: 'USD',
printDetails() {
console.log(`The symbol is the ${this.symbol} and the currency is ${this.currency}.`)
},
},
}
america.details.printDetails()
Output"The symbol is the eagle and the currency is USD."
Another way of thinking about it is that this
refers to the object on the left side of the dot when calling a method.
When you use the new
keyword, it creates an instance of a constructor function or class. Function constructors were the standard way to initialize a user-defined object before the class
syntax was introduced in the ECMAScript 2015 update to JavaScript. In Understanding Classes in JavaScript, you will learn how to create a function constructor and an equivalent class constructor.
function Country(name, yearFounded) {
this.name = name
this.yearFounded = yearFounded
this.describe = function() {
console.log(`${this.name} was founded in ${this.yearFounded}.`)
}
}
const america = new Country('The United States of America', 1776)
america.describe()
Output"The United States of America was founded in 1776."
In this context, this
is now bound to the instance of Country
, which is contained in the america
constant.
A constructor on a class acts the same as a constructor on a function. Read more about the similarities and differences between function constructors and ES6 classes in Understanding Classes in JavaScript.
class Country {
constructor(name, yearFounded) {
this.name = name
this.yearFounded = yearFounded
}
describe() {
console.log(`${this.name} was founded in ${this.yearFounded}.`)
}
}
const america = new Country('The United States of America', 1776)
america.describe()
this
in the describe
method refers to the instance of Country
, which is america
.
Output"The United States of America was founded in 1776."
In the browser, there is a special this
context for event handlers. In an event handler called by addEventListener
, this
will refer to event.currentTarget
. More often than not, developers will simply use event.target
or event.currentTarget
as needed to access elements in the DOM, but since the this
reference changes in this context, it is important to know.
In the following example, we’ll create a button, add text to it, and append it to the DOM. When we log the value of this
within the event handler, it will print the target.
const button = document.createElement('button')
button.textContent = 'Click me'
document.body.append(button)
button.addEventListener('click', function(event) {
console.log(this)
})
Output<button>Click me</button>
Once you paste this into your browser, you will see a button appended to the page that says “Click me”. If you click the button, you will see <button>Click me</button>
appear in your console, as clicking the button logs the element, which is the button itself. Therefore, as you can see, this
refers to the targeted element, which is the element we added an event listener to.
In all of the previous examples, the value of this
was determined by its context—whether it is global, in an object, in a constructed function or class, or on a DOM event handler. However, using call
, apply
, or bind
, you can explicitly determine what this
should refer to.
It is difficult to define exactly when to use call
, apply
, or bind
, as it will depend on the context of your program. bind
can be particularly helpful when you want to use events to access properties of one class within another class. For example, if you were to write a simple game, you might separate the user interface and I/O into one class, and the game logic and state into another. Since the game logic would need to access input, such as key press and click, you would want to bind
the events to access the this
value of the game logic class.
The important part is to know how to determine what object this
refers to, which you can do implicitly with what you learned in the previous sections, or explicitly with the three methods you will learn next.
call
and apply
are very similar—they invoke a function with a specified this
context, and optional arguments. The only difference between call
and apply
is that call
requires the arguments to be passed in one-by-one, and apply
takes the arguments as an array.
In this example, we’ll create an object, and create a function that references this
but has no this
context.
const book = {
title: 'Brave New World',
author: 'Aldous Huxley',
}
function summary() {
console.log(`${this.title} was written by ${this.author}.`)
}
summary()
Output"undefined was written by undefined"
Since summary
and book
have no connection, invoking summary
by itself will only print undefined
, as it’s looking for those properties on the global object.
Note: Attempting this in strict mode would result in Uncaught TypeError: Cannot read property 'title' of undefined
, as this
itself would be undefined
.
However, you can use call
and apply
to invoke the this
context of book
on the function.
summary.call(book)
// or:
summary.apply(book)
Output"Brave New World was written by Aldous Huxley."
There is now a connection between book
and summary
when these methods are applied. Let’s confirm exactly what this
is.
function printThis() {
console.log(this)
}
printThis.call(book)
// or:
whatIsThis.apply(book)
Output{title: "Brave New World", author: "Aldous Huxley"}
In this case, this
actually becomes the object passed as an argument.
This is how call
and apply
are the same, but there is one small difference. In addition to being able to pass the this
context as the first argument, you can also pass additional arguments through.
function longerSummary(genre, year) {
console.log(
`${this.title} was written by ${this.author}. It is a ${genre} novel written in ${year}.`
)
}
With call
each additional value you want to pass is sent as an additional argument.
longerSummary.call(book, 'dystopian', 1932)
Output"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
If you try to send the exact same arguments with apply
, this is what happens:
longerSummary.apply(book, 'dystopian', 1932)
OutputUncaught TypeError: CreateListFromArrayLike called on non-object at <anonymous>:1:15
Instead, for apply
, you have to pass all the arguments in an array.
longerSummary.apply(book, ['dystopian', 1932])
Output"Brave New World was written by Aldous Huxley. It is a dystopian novel written in 1932."
The difference between passing the arguments individually or in an array is subtle, but it’s important to be aware of. It might be simpler and more convenient to use apply
, as it would not require changing the function call if some parameter details changed.
Both call
and apply
are one-time use methods—if you call the method with the this
context it will have it, but the original function will remain unchanged.
Sometimes, you might need to use a method over and over with the this
context of another object, and in that case you could use the bind
method to create a brand new function with an explicitly bound this
.
const braveNewWorldSummary = summary.bind(book)
braveNewWorldSummary()
Output"Brave New World was written by Aldous Huxley"
In this example, every time you call braveNewWorldSummary
, it will always return the original this
value bound to it. Attempting to bind a new this
context to it will fail, so you can always trust a bound function to return the this
value you expect.
const braveNewWorldSummary = summary.bind(book)
braveNewWorldSummary() // Brave New World was written by Aldous Huxley.
const book2 = {
title: '1984',
author: 'George Orwell',
}
braveNewWorldSummary.bind(book2)
braveNewWorldSummary() // Brave New World was written by Aldous Huxley.
Although this example tries to bind braveNewWorldSummary
once again, it retains the original this
context from the first time it was bound.
Arrow functions do not have their own this
binding. Instead, they go up to the next level of execution.
const whoAmI = {
name: 'Leslie Knope',
regularFunction: function() {
console.log(this.name)
},
arrowFunction: () => {
console.log(this.name)
},
}
whoAmI.regularFunction() // "Leslie Knope"
whoAmI.arrowFunction() // undefined
It can be useful to use the arrow function in cases where you really want this
to refer to the outer context. For example, if you had an event listener inside of a class, you would probably want this
to refer to some value in the class.
In this example, you’ll create and append button to the DOM like before, but the class will have an event listener that will change the text value of the button when clicked.
const button = document.createElement('button')
button.textContent = 'Click me'
document.body.append(button)
class Display {
constructor() {
this.buttonText = 'New text'
button.addEventListener('click', event => {
event.target.textContent = this.buttonText
})
}
}
new Display()
If you click the button, the text content will change to the value of buttonText
. If you hadn’t used an arrow function here, this
would be equal to event.currentTarget
, and you wouldn’t be able to use it to access a value within the class without explicitly binding it. This tactic is often used on class methods in frameworks like React.
In this article, you learned about this
in JavaScript, and the many different values it might have based on implicit runtime binding, and explicit binding through bind
, call
, and apply
. You also learned about how the lack of this
binding in arrow functions can be used to refer to a different context. With this knowledge, you should be able to determine the value of this
in your programs.
#javascript
1594896120
Working with JavaScript “this” keyword can be tricky. Not knowing the background rules may end up with the famous “it works, but I don’t know why” or worse: “it doesn’t work and I don’t know why”. It’s good to know the theory before putting things into practice. Call(), Apply() and Bind() methods can come in handy when setting the “this” value.
This tutorial covers call(), apply() and bind() methods. A multiple basic examples have been provided.
var car = {
registrationNumber: "GA12345",
brand: "Toyota",
displayDetails: function(){
console.log(this.registrationNumber + " " + this.brand);
}
}
The above will work perfectly fine as long as we use it this way:
car.displayDetails(); // GA12345 Toyota
But what if we want to borrow a method?
var myCarDetails = car.displayDetails;
myCarDetails();
Well, this won’t work as the “this” will be now assigned to the global context which doesn’t have neither the registrationNumber nor the brand property.
#javascript #programming #call #apply #bind methods
1593507275
These functions are very important for every JavaScript Developer and are used in almost every JavaScript Library or Framework. Check out the code snippet below.
Taken from the very popular library Lodash
/**
* Creates a function that invokes `func` with arguments reversed.
*
* @since 4.0.0
* @category Function
* @param {Function} func The function to flip arguments for.
* @returns {Function} Returns the new flipped function.
* @see reverse
* @example
*
* const flipped = flip((...args) => args)
*
* flipped('a', 'b', 'c', 'd')
* // => ['d', 'c', 'b', 'a']
*/
function flip(func) {
if (typeof func !== 'function') {
throw new TypeError('Expected a function')
}
return function(...args) {
return func.apply(this, args.reverse())
}
}
export default flip
Look at the statement on line 21, return func.apply(this, args.reverse())
In this article, we will have a look at the call(), apply() and bind() methods of JavaScript. Basically these 3 methods are used to control the invocation of the function. The call() and apply() were introduced in ECMAScript 3 while bind() was added as a part of ECMAScript 5.
Let us start with an example to understand these.
Suppose you are a student of X university and your professor has asked you to create a math library, for an assignment, which calculates the area of a circle.
const calcArea = {
pi: 3.14,
area: function(r) {
return this.pi * r * r;
}
}
calcArea.area(4); // prints 50.24
You test this and verify its result, it is working fine and you upload the library to portal way before the deadline ends. Then you ask your classmates to test and verify as well, you come to know that that your result and their results mismatches the decimals precision. You check the assignment guidelines, Oh no! The professor asked you to use a constant **pi** with 5 decimals precision. But you used **3.14** and not **3.14159** as the value of pi. Now you cannot re-upload the library as the deadline date was already over. In this situation, **call()** function will save you.
#js #javascript-development #javascript #javascript-interview #javascript-tips
1598947500
Javascript binding is done using the Bind() method. With the help of the bind method, we can make one common function and bind different objects, so that the function gives different results when its need. otherwise, it gives the same result or gives an error while the code is executing.
In short, when a function or method is invoked, the bind() method allows us to easily set which object will be bound by this keyword.
var info= {
name : "XYZ",
printFunc: function(){
document.write(this.name);} // XYZ
}
info.printFunc();
In the above example, there is no problem accessing the name, this keyword bind the name variable to the function. This is called as default binding.
This keyword will here point to object i.e info object.
var info = {
name : "XYZ",
printFunc: function(){
document.write(this);// window object or undefined(strict mode).
document.write(this.name);
}
}
var printFunc2= info.printFunc;
printFunc2();
In the above example, we are storing a reference of info.printFunc
to printFunc2
variable. After that, we are calling it without an object reference, so this
will now refer to the window (global) object or undefined (in strict mode). Hence, the binding of this is lost, so no output is produced.
So basically, the Bind() method is used so that binding of this is not lost.
By using bind() method we can set the context of _this or in simple terms we can bind this _to a particular object.
How to use bind?
bind()
method creates a new function, when invoked, has the this
sets to the provided value. See example below:-var car1 = {
name : "swift",
color: "red",
}
var car2 = {
name : "alto",
color: "blue",
}
function infoFunc() {
document.write(this.name + " " + this.color + "<br/>");
}
infoFunc.bind(car1)(); // swift red
infoFunc.bind(car2)(); // alto blue
There is one common function infoFunc() which is invoked 2times with different objects so that different results are produced. This first binds to car1 object and then to car2 object.
2. Function borrowing which means the bind()
allows an object to borrow a method from another object without making a copy of that method.
#this-keyword #binding #javascript #front-end-development #call-apply-bind
1589255577
As a JavaScript developer of any level, you need to understand its foundational concepts and some of the new ideas that help us developing code. In this article, we are going to review 16 basic concepts. So without further ado, let’s get to it.
#javascript-interview #javascript-development #javascript-fundamental #javascript #javascript-tips
1622207074
Who invented JavaScript, how it works, as we have given information about Programming language in our previous article ( What is PHP ), but today we will talk about what is JavaScript, why JavaScript is used The Answers to all such questions and much other information about JavaScript, you are going to get here today. Hope this information will work for you.
JavaScript language was invented by Brendan Eich in 1995. JavaScript is inspired by Java Programming Language. The first name of JavaScript was Mocha which was named by Marc Andreessen, Marc Andreessen is the founder of Netscape and in the same year Mocha was renamed LiveScript, and later in December 1995, it was renamed JavaScript which is still in trend.
JavaScript is a client-side scripting language used with HTML (Hypertext Markup Language). JavaScript is an Interpreted / Oriented language called JS in programming language JavaScript code can be run on any normal web browser. To run the code of JavaScript, we have to enable JavaScript of Web Browser. But some web browsers already have JavaScript enabled.
Today almost all websites are using it as web technology, mind is that there is maximum scope in JavaScript in the coming time, so if you want to become a programmer, then you can be very beneficial to learn JavaScript.
In JavaScript, ‘document.write‘ is used to represent a string on a browser.
<script type="text/javascript">
document.write("Hello World!");
</script>
<script type="text/javascript">
//single line comment
/* document.write("Hello"); */
</script>
#javascript #javascript code #javascript hello world #what is javascript #who invented javascript