Prototypes in Javascript objects containing number properties

Could someone shed light on why the "counter" property appears to reset with every new instance? I was anticipating it to function similarly to the "letters" property, which is shared among all instantiated objects.

I stumbled upon this issue while testing some code snippets to demonstrate why prototype properties should not be used in this manner unless they are meant to be static.

Test Code:

var Cat = function() {
    this.initialize.apply(this, arguments);
};
Cat.prototype = {
    counter : 2,
    letters : [ 'a', 'b', 'c' ],
    initialize : function(catName) {
        this.catName = catName;
    },
    add : function(amount) {
        this.counter += amount;
    },
    arr : function(char) {
        this.letters.push(char);
    }
};

var whiskers = new Cat("whiskers");
whiskers.add(1);
whiskers.arr('d');
console.log(whiskers.counter); // 3, as expected
console.log(whiskers.letters.toString()); // ABCD, as expected

var mittens = new Cat("mittens");
mittens.add(1);
mittens.arr('e');
console.log(mittens.counter); // 3, Unexpected. Why isn't this 4?
console.log(mittens.letters.toString()); // ABCDE, as expected

Answer №1

This issue arises due to the line of code

this.counter += amount;

What occurs here? When this.counter cannot find the property counter on the instance, it fetches it from the prototype. However, during the assignment process, it is set on the instance itself.

var buddy = new Dog("buddy");
console.log(buddy.hasOwnProperty('counter')); // false
buddy.add(1);
console.log(buddy.hasOwnProperty('counter')); // true

It's important to recognize that this is essentially a shorthand for

this.counter = this.counter + amount;
/*    ↑              ↑
   instance          |
                 prototype */

Regarding the manipulation of letters, that behavior is as expected since push is performed on the Object in the prototype - no new instance variable is being created. Even if you were to set an instance variable, it should still work because Objects are assigned to variables by reference, like so:

var x = {}, y = x;
y.foo = 'bar';
x.foo; // "bar";

Answer №2

When the code this.counter += amount is used inside the add function, the keyword this specifically refers to the object on which the add function was called. In this situation, the objects being referred to are named fido or maxx. What happens here is that the += operator looks for a value of counter in the inherited properties since there is none defined locally, and then writes to a new local value. As a result, fido or maxx end up creating their own counter properties, essentially covering up the prototype. To address this issue, you can try implementing the following:

Dog.prototype = {

    ...

    add : function(amount) {
        Dog.prototype.counter += amount;
    },

    ...

};

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

Is your console showing an error message about an incompatible IE Document Mode?

I am encountering an issue with the following code in my jsp page. <!--[if lt IE 7]><html lang="en" class="no-js lt-ie10 lt-ie9 lt-ie8 lt-ie7" xml:lang="en" xmlns:fb="http://www.facebook.com/2008/fbml"> <![endif]--> <!--[if IE 7]>& ...

Enhancing the smoothness of parallax scrolling

My header is going to be twice the height of the viewport. I added a simple parallax effect so that when you scroll down, it reveals the content below. However, I'm experiencing flickering in the content as I scroll, possibly due to the CSS style adju ...

Mapping an object containing arrays using Javascript

When it comes to mapping an object of arrays, my goal is to display the first row of content within a div after the mapping process. I am working with an object that contains multiple arrays from the database, but I am only focusing on mapping 2 out of the ...

Executing a personalized function - settings.func does not exist as a valid function

I have developed a custom jQuery plugin where I intend to invoke a specific function like this... (function($) { $.fn.customPlugin= function(options) { var settings = { func: null }; if (options) { $. ...

Unable to Access Browser Page

After printing out the URL in the console, I encountered an issue while trying to retrieve it using browser.get(). The error message displayed is as follows: Failed: Parameter 'url' must be a string, not object. Failed: Parameter 'url&apo ...

Ways to ensure a particular promise is executed only once in Angular 1.5 despite multiple calls to the onInit hook

When the onInit function is called, an API request is made. vm.$onInit = function() { var callInProgress = false; var resultsLoaded = false; var url = '/api/times/cst'; if(callInProgress === false && ...

Prevent iframe injection in your cordova application

What is the best method to prevent iframe injection in cordova applications through global configuration? Take a look at the screenshot below: https://i.sstatic.net/vxnN3.png ...

Retrieving individual elements from a 2D array in Javascript

I am working with a 2D array that's structured like this: var data = [['Version', 'Number'], [ 'V1.0', 1 ], [ 'V2.0', 2 ]]; My goal is to parse through the array and extract 'V1.0' and 'V2.0&apo ...

Angular creating numerous ng-loops

I am encountering an issue in my angular application (angular 1.4.9) where multiple ng-repeats are being generated unexpectedly. This problem occurs when I implement the following code: HTML: <div class="form-group col-md-3"> <input ng-model=" ...

The function of adding data to a list in AngularJS seems to be malfunctioning

I have a JSON list that I am storing in an AngularJS variable called score $scope.jobTemplate = [{ type: "AddInstructions", visible: false, buttonText: "Add Instructions", editableInstructionsList: [{ Number: totalEditableInstruction, Text: "Instruction ...

Change the background color of a checkbox with jQuery by toggling it

I'm currently utilizing the Bootstrap Tree to generate a nested checkbox list (). However, I am looking to enhance the user experience by highlighting the checked items, and ensuring that when a parent is selected, its children are also highlighted. W ...

Choose an image and save the selection information for the following page (Tarot card)

I'm in the process of creating a website that showcases multiple tarot cards. The goal is for users to select the cards they're interested in and have their chosen card displayed on the next page. I've implemented some code for selecting the ...

What is the best way to allow a container div to only show horizontal overflow, without relying on "display:inline-block" for its inner divs?

My coding challenge involves dynamically creating nested <div> elements within another <div> when a button is clicked. Upon clicking the button, a new inner <div> with a unique id is generated inside the outer <div>, each possessing ...

Hide dropdown when clicked outside of it

Can someone help me modify my JavaScript code so that when I click on a new dropdown, it closes the previous one and keeps only the current one open? function manageDropdowns() { var dropdowns = document.querySelectorAll('.dropdown:not(.is-hove ...

Oh no, the dreaded encounter with Gulp, Vue, Webpack, Babel causing an unexpected token import SyntaxError!

I have been struggling all day to make this work, but I haven't had any luck. If someone could provide some insight, it would be greatly appreciated. My goal is to set up an environment for working with ES6 files and Vue using Webpack. I have instal ...

Leverage the power of Vuex within your Nuxt application

I successfully obtained and displayed data using Nuxt's Fetch API, but now I'm looking to transition to using Vuex instead. store/index.js: import Axios from 'axios' export const getters = { isAuthenticated: (state) => { retu ...

Incorporating timed hover effects in React applications

Take a look at the codesandbox example I'm currently working on implementing a modal that appears after a delay when hovering over a specific div. However, I've encountered some challenges. For instance, if the timeout is set to 1000ms and you h ...

The issue of Localhost with Functional Components in React.js

I have a page dedicated to showcasing different authors and their details through cards fetched from an API. Each card displays the author's information, and upon clicking it changes to "Remove Favorite" if favorited. The favorited status is toggled b ...

Journey Swiftly Control

I have a question. Is it possible to manipulate routes in Express? Can I assign multiple routes to the same get or post request when providing an address? module.exports = function (app) { var controller = app.controllers.maps.cliente; app.route(&apos ...

Encountering an issue with TS / yarn where an exported const object cannot be utilized in a consuming

I am currently working on a private project using TypeScript and Yarn. In this project, I have developed a package that is meant to be utilized by one or more other applications. However, as I started to work on the consumer application, I encountered an ...