The usage of Arrow Functions within Object Literal Syntax

I can't seem to understand why an arrow function within an object literal is invoked with window as the context for this. Any insights on this would be greatly appreciated.

var arrowObject = {
  name: 'arrowObject',
  printName: () => {
    console.log(this);
  }
};

// Outputs: Window {external: Object, chrome: Object ...}
arrowObject.printName();

On the other hand, here's an object that behaves as expected:

var functionObject = {
  name: 'functionObject',
  printName: function() {
    console.log(this);
  }
};

// Outputs: Object {name: "functionObject"}
functionObject.printName();

As per observations in the Babel REPL, it appears they are transpiled like so:

var arrowObject = {
  name: 'arrowObject',
  printName: function printName() {
    console.log(undefined);
  }
};

This contrasts with:

var functionObject = {
  name: 'functionObject',
  printName: function printName() {
    console.log(this);
  }
};

The question remains: Why does arrowObject.printName(); not have arrowObject as the value of this?

Logs were generated using Fiddle (with no use strict; directive).

Answer №1

Remember that the Babel translation assumes strict mode, while the use of window in your code indicates that you are running it in loose mode. If you switch Babel to assume loose mode, the transpilation will be differently:

var _this = this;                    // **

var arrowObject = {
  name: 'arrowObject',
  printName: function printName() {
    console.log(_this);              // **
  }
};

Take note of the _this global and console.log(_this);, as opposed to console.log(undefined); in the strict-mode transpilation of your code.

I'm trying to understand why an arrow function within an object literal has window as its this.

This happens because arrow functions inherit their this value from the context in which they are created. When you do this:

var arrowObject = {
  name: 'arrowObject',
  printName: () => {
    console.log(this);
  }
};

...the value of this is window. (This implies that you are not using strict mode; I suggest using it unless there is a specific reason not to.) If it were something else, such as the undefined value in the global strict mode context, then this within the arrow function would instead refer to that value.

The context in which the arrow function is created may become clearer if we break down your initializer into its equivalent logical form:

var arrowObject = {};
arrowObject.name = 'arrowObject';
arrowObject.printName = () => {
  console.log(this);
};

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Tips for incorporating an additional dataset bar using chart.js

I'm having a bit of trouble trying to modify the following script. Currently, it only displays one bar per label, but I need it to show 2 bars per label. Despite my numerous attempts using different variations with and without commas and "{}", I can&a ...

JavaScript code encounters a math calculator script error

Am I overlooking something in my script? Everything seems to work fine when I click the minus (-) button, but when I press the plus (+) button, the calculator malfunctions. It displays 1, 11, 21, and so on, all ending with 1... Here is my code: functi ...

Can React-Select be utilized in the browser directly from the CDN?

Is it possible to utilize react-select directly in the browser without using bundlers nowadays? The most recent version that I could find which supports this is 2.1.2: How to import from React-Select CDN with React and Babel? In the past, they provided r ...

Mapping an array of objects within another array of objects

I have a collection of objects that I looped through to extract the content: const teamSliderContent = [ { Description1: 'Chef. Mordy Wenk', Title: 'Head of the Chief staff.', id: 1, }, { Desc ...

Attempting to insert items into a storage array and subsequently outputting them using a loop

I am attempting to add "contacts" to local storage, and every time I add a new contact I want to refresh it in a jQuery list. I have successfully achieved this without using local storage. However, now I am facing a problem that I can't seem to solve. ...

Is there a way to invoke a function using a variable in place of its actual name?

Check out my code snippet: $('.click').on('click', function(){ $.ajax({ url : $(this).siblings('a').attr('href'), dataType : 'JSON', success : function (tags) { $ ...

Exploring MongoDB through User Interface Requests

As part of a project to develop a minimalist browser-based GUI for MongoDB, an interesting question has arisen. How can we accurately display the current state of the database and ensure it is continuously updated? Specifically, what methods can be utiliz ...

Reorganizing Arrays in Javascript: A How-To Guide

I have an array in JavaScript called var rows. [ { email: '<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="81f4f2e4f3b0c1e4f9e0ecf1ede4afe2eeec">[email protected]</a>' }, { email: '<a hre ...

Jest test encounters an error due to an unexpected token, looking for a semicolon

I've been working on a Node project that utilizes Typescript and Jest. Here's the current project structure I have: https://i.stack.imgur.com/TFgdQ.png Along with this tsconfig.json file "compilerOptions": { "target": "ES2017", "modu ...

Is it possible to trigger a JavaScript function by manipulating the URL of an HTML page?

Imagine this scenario: You have an HTML page located at example.com/test.html that contains several pre-defined JavaScript functions, including one named play(). How can I add JavaScript to the URL in order to automatically trigger the play() function wh ...

Await that's locked within a solo asynchronous function

async function submitForm(e){ e.preventDefault() console.log(e.target) try { const response = await axios.post('/api/<PATH>', {username, password}); console.log(response.data); const token = response.data.token if (t ...

"Utilizing FabricJs with Multiple Canvases to Display the Same Image Repeatedly

Within a loop ranging from 1 to 2, I have created two canvases on the screen and stored them in an object. However, when I load the same two images onto each canvas, only the last canvas displays the images. Why is it not loading on both canvases? Interest ...

Obtain a masterpiece by creating a canvas in React

Greetings! I have developed a drawing app using react and I am looking for a way to capture what the user has drawn on the canvas when they release the mouse button. This process should repeat continuously until the user stops drawing. Can anyone suggest h ...

Ways to specify the default value for a component

A sample of my custom component code (Amount.tsx) is shown below: const Price = ({ price, prevPrice }) => { return ( <div className="product-amount"> <div className="price"> {prevPrice ? (<del class ...

Tips for halting all YouTube videos in a Reactjs environment

I am currently working with React.js and using Next.js. I have implemented a "YouTube video slider" and now I am looking for a way to stop all videos when a button is clicked. Can anyone provide guidance on how to achieve this? Below is the code snippet ...

Struggling with Mocha, supertest, and passport when testing authenticated routes with JWT authentication

I've been experimenting with testing authenticated routes in Mocha, but I've run into an issue where the user created in the `before` or `beforeEach` hooks doesn't persist. Here's a snippet from my test.js: const should = require(&apo ...

Developing a vue.js component library without the need for constant rebuilding after every edit

Introduction: I have created two projects using vue-cli ~4.2.0: parent-app - the main project dummylib - a library that is imported by parent-app. It contains several .vue components. Currently, parent-app functions well in dev mode with dummylib being ...

Troubleshooting issue with Express.json() functionality in the latest release of version 4.17

I'm currently exploring the MEAN stack and I am focused on performing CRUD operations. However, when I send data in the request body from Angular to the server, I end up receiving an empty request body. I'm unsure of where I might be making a mis ...

Outputting messages to a component with React

I'm attempting to create a component similar to a console where messages are displayed one after the other instead of replacing the old message. My goal is to have a component where I can input strings, like in a chatbox, using different parts of my ...

The minification of HTML scripts may cause problems with the <script> tag

Greetings! I have a PHP script that is used to minify the page by removing any comments or spaces. Here is the script: <?php function sanitize_output($buffer) { $search = array( '/\>[^\S ]+/s', '/[^&b ...