A guide on incorporating a method using ES6 Rest into a JavaScript object

My goal is to enhance my Person constructor by adding a method that allows users to add friends. I wanted to utilize the "rest" feature of ES6 to pass a variable number of friends, but I seem to be stuck. My initial attempt resulted in an error ("Uncaught TypeError: f.addFriends is not a function(…)"):

// Persons creator
function Person(name){
    this.name = name;
    this.friends = [];
    this.addFriends = function(...a){
      a.forEach(function(d){this.friends.push(d)});
    }
}

// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);

I also tried the following code (no error, but no friends were added):

// Persons creator
function Person(name){
    this.name = name;
    this.friends = [];
}

Person.prototype.addFriends = function(...a){
   a.forEach(function(d){this.friends.push(d)});
}


// Create three persons
f = new Person("Fanny");
e = new Person("Eric");
j = new Person("John");

// add Eric & Fanny as friends of Fanny
f.addFriends(e,j);

Do you know what I'm doing wrong? Thank you for your assistance!

Answer №1

forEach requires a callback function, which is typically executed in the global context (referred to as window in the browser). To address the issue of scope, you can pass the current value of this as the second argument when using forEach.

Alternatively, you can sidestep the this dilemma entirely by simply combining the arrays using the concat method:

function Person(name){
    this.name = name;
    this.friends = [];
    this.addFriends = function(...newFriends){
      this.friends = this.friends.concat(newFriends);
    }
}

Answer №2

this, in the callback function passed to forEach, does not refer to your specific instance of Person within this code snippet:

Person.prototype.addFriends = function(...a){
   a.forEach(function(d){this.friends.push(d)});
}

To ensure the correct context, you can utilize an arrow function like this:

Person.prototype.addFriends = function(...a){
   a.forEach((d) => {this.friends.push(d)});
}

However, an even more elegant solution is available here:

Person.prototype.addFriends = function(...a){
   this.friends.push(...a);
}

Answer №3

When utilizing a callback within the forEach method, the reference of this does not point to the object itself. To correct this, bind the callback function to this:

Person.prototype.addFriends = function(...a){
   a.forEach(function(d){this.friends.push(d)}.bind(this));
}

In modern ES6 syntax, you have the option to use an arrow function, which automatically binds the lexical value of this:

Person.prototype.addFriends = function(...a){
   a.forEach((d) => this.friends.push(d));
}

Answer №4

A brand new feature introduced in ECMAScript 6 is the use of classes

  1. To start, you define your class:

    class User {

    constructor(username) {
        this.username = username;
        this.posts = [];
    }
    
    addPost(posts) {
        // do something with posts
        this.posts = posts;
    }
    

    }

After defining your class, you can create new instances of the User

var u = new User("Alice");

and add some posts

p.addPost(....)

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

Navigating the Basics: Understanding the Four Quadrant Selection Grid in a Material UI & React Pop-Up Form

Sorry if these questions seem silly. I'm diving into React & Material-UI without a mentor to guide me, relying on documentation and tutorials. Is there a better place for quick beginner questions? Maybe a chat forum or Slack group? Not sure if Stack i ...

Sending data with the request body using Express and Passport

I've created a login application using Express and Passport, but I'm having trouble directing the user to their specific user profile page. The goal is for users to fill out an HTML form and then be redirected to their own profile page (which dif ...

The function returning the map finished before the foreach loop

I recently created a program that computes totals by multiplying a given rate with some hours. However, I've encountered an issue with the getTasks() function always returning an empty map. Even though the fields entered in the map are not empty, the ...

The Node.js Express server does not provide access to certain static files

I am currently utilizing the angularjs-gulp-browserify-boilerplate for my development environment on Windows 10. Once I run gulp in dev mode, static files are moved to the build directory: ./build |_js |_css |_img |_fonts |_lang In additio ...

Bootstrap 4 modal experiencing issues with the form end tag functionality

Currently, I am facing an issue while attempting to incorporate a confirmation delete feature using a Bootstrap 4 modal in my Laravel project. The problem arises when the modal is opened, and the submit button fails to function. Upon inspecting the browser ...

On startup of the chrome app, read and load a JSON file into a variable

As I develop a chrome app, my goal is to store all configuration defaults in json file(s) alongside other assets. I am currently using AJAX requests to load them, but I'm wondering if there is a more efficient way to handle this. Is there perhaps an o ...

What is the best way to incorporate modal window parameters into this code snippet?

JavaScript function: function loadBlockEditor(block, username) { var blockInfo = $.ajax({ url: "in/GameElement/BlockEditor.php", type: "GET", data: 'block=' + block + '&nick=' + username, dataType: "html" }); b ...

Leverage jQuery to automatically submit an ajax form once all ajax requests have been successfully executed

I have integrated a WordPress plugin for store locator on my website. For pages without the interactive map, I have set up a form that serves as a location search tool. To clarify, the form includes a location field where users can input their desired loc ...

Is jQuery's $.trim() function reliable or poorly implemented?

$.trim() utilizes a specific RegExp pattern to trim a string: /^(\s|\u00A0)+|(\s|\u00A0)+$/g However, this can lead to some issues, as demonstrated in the following example: var mystr = ' some test -- more text ...

Retrieve the values of a particular key from your Django queryset JSON data and then seamlessly send them over to VueJS

I recently developed a web app using Django2 with Vue for the frontend. I encountered an issue in passing all values of a specific key from JSON data to a JavaScript dictionary value on the frontend. Despite trying to use the += operator to add the data, I ...

Removing the hash symbol in Angular: A step-by-step guide

My experience with AngularJS is new, and I am currently working on removing the # from the URLs without utilizing NODE or Express. The project is being hosted locally on MAMP, with index.html acting as the main entry point. Within the structure, there are ...

MUI Tutorial: Displaying Text with Line Breaks

Whenever I input text into the MUI Textfield, it displays without any line breaks. Is there a more effective solution available? <Stack direction="row" alignItems="start" justifyContent="start" mb={5}> <TextFie ...

Stop HTML <dialog> from automatically closing using Vue

I'm working on a project where I need to use Vue to programmatically prevent an HTML dialog element from closing when the close event is triggered. Here's the code snippet I am currently using: import {ref} from 'vue'; const dialogTe ...

A guide to utilizing the spread operator within a typescript tuple

Is it possible to set the structure of an array without knowing the exact number of elements it will contain? How can I achieve this flexibility in defining array configurations? (Check out a playground version here): type numStrArr = [number, ...string]; ...

Playing embedded YouTube videos automatically in Safari 11 without user interaction

I’m encountering an issue with a simple modal dialog: When a user clicks on a button, the modal overlay appears. An embedded YouTube <iframe> is then added. Everything works smoothly in most browsers, except for Safari 11.1. Safari’s new auto ...

Utilize the csv-parser module to exclusively extract the headers from a file

Recently, I've been exploring the NPM package csv-parser which is designed to parse CSV files into JSON format. The example provided demonstrates how you can read a CSV file row by row using the following code snippet: fs.createReadStream('data.c ...

Function activation in Element requires a double click to initiate

I've encountered an issue with a web element I'm working on where the click function only triggers after the first click, rendering the initial click ineffective. Here's the code snippet in question: HTML: <div> <a href="#0" cla ...

Determining the Maximum Number of Characters Allowed in a Div Using jQuery

Could anyone provide guidance on how to populate a div with single characters? I want the div to span the width of the viewport. The code to get the width is: $(window).width(); I would like JavaScript to generate HTML similar to this: <div id="text ...

Refresh required to showcase newly created items

Currently, I am developing a straightforward tool that allows users to assign budgets to teams. This tool operates in a manner similar to a standard to-do list. The delete function functions smoothly without requiring a reload. However, the create functio ...

What is the best way to create a reusable component for a Material-UI Snackbar?

Having trouble getting my Alert component to display a message that says "Successfully submitted" in the parent component. The message doesn't seem to be showing up. AlertComponent import React, { useState } from "react"; import { Snackbar, Alert } f ...