The synergy between Object.prototype and the bind() method

Currently, I am delving into ngInfiniteScroll while being a novice in JavaScript. Upon reviewing the demo of ngInfiniteScroll, I find it quite challenging to comprehend why Reddit.nextPage has been altered to Reddit.prototype.nextPage, and how the bind() method is utilized to encapsulate a segment of the Reddit.prototype.nextPage function.

Below is the code snippet:

myApp.controller('DemoController', function($scope, Reddit) {
  $scope.reddit = new Reddit();
});

// Reddit constructor function for handling HTTP requests and pagination logic
myApp.factory('Reddit', function($http) {
  var Reddit = function() {
    this.items = [];
    this.busy = false;
    this.after = '';
  };

  Reddit.prototype.nextPage = function() {
    if (this.busy) return;
    this.busy = true;

    var url = "https://api.reddit.com/hot?after=" + this.after + "&jsonp=JSON_CALLBACK";
    $http.jsonp(url).success(function(data) {
      var items = data.data.children;
      for (var i = 0; i < items.length; i++) {
        this.items.push(items[i].data);
      }
      this.after = "t3_" + this.items[this.items.length - 1].id;
      this.busy = false;
    }.bind(this));
  };

  return Reddit;
});

I've recently grasped the concept that utilizing this allows access to properties within the Reddit object.

Could it be that because var Reddit is assigned an anonymous function, I need to bind the this from the anonymous function to the this in Reddit.nextPage so they refer to the same properties?

However, it appears feasible to access those properties even without using the bind() method. Consider the following example:

if (this.busy) return;
this.busy = true;

I have scoured through several articles on this topic but none provide an in-depth explanation, leaving me utterly confused.

Answer №1

Exploring these functions:

Twitter.prototype.loadTweets = function() {
    // main function
    ...    
    $http.get(url).then(function(response) {
      // nested function
    }.bind(this));
  };

If we don't bind, the context of this in the inner function will be different, making it access different properties. However, using bind(this) instructs the inner function to refer to this from the main function's scope.

For further insights, I suggest reading this informative piece.

Answer №2

Although I haven't had the chance to explore the blog post yet, my assumption is that it was relocated to the prototype for the purpose of automatic inclusion in every instance of your "Reddit" service. Each time a new service is created, this method will be included because all prototype methods are inherited automatically.

As for the bind function, when passing a function as an argument, it loses its original context upon execution. This means it will no longer be bound to your Reddit service, instead taking on a new scope of execution. Consequently, references to this.items, this.busy, and this.after would all become undefined and lead to errors.

To delve deeper into this topic, you can learn more about bind(), call(), and apply().

Answer №3

this can vary depending on the context. Here's an example:

var foo = {
  bar: function() {
    console.log(this.baz);
  },
  baz: 3
};

foo.bar(); // logs 3

However, in an asynchronous callback, the context changes. For instance, consider using setTimeout:

var foo = {
  bar: function() {
    setTimeout(function() { console.log(this.baz); }, 0);
  },
  baz: 3
};

foo.bar(); // logs undefined or throws an error in strict mode

In this case, 'this' no longer refers to foo. To work around this limitation, we can use bind:

var foo = {
  bar: function() {
    setTimeout((function() { console.log(this.baz); }).bind(this), 0);
  },
  baz: 3
};

foo.bar(); // logs 3

By binding the context to foo (the value of this at the call site), we are able to achieve the desired outcome. This is similar to how this is handled in the success handler of a promise returned by $http.jsonp.

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

The Javascript Date constructor struggles to interpret date strings in certain timezones that are not enclosed in brackets

Take a look at the examples below: new Date("Wed, 28 May 2014 09:50:06 EEST"); // Invalid Date new Date("Thu, 26 Jun 2014 09:09:27 EDT"); // OK, is parsed new Date("Wed, 28 May 2014 09:50:06 (EEST)"); // OK, is parsed new Date("Thu, 26 Jun 2014 09:09:27 ( ...

The Vue.JS application encountered an error while making an API request, resulting in an uncaught TypeError: Cannot read properties of undefined related to the 'quote'

<template> <article class="message is-warning"> <div class="message-header"> <span>Code Examples</span> </div> <div class="message-body"> ...

Ways to determine if the mouse is positioned at the bottom of a div area

I have multiple sections and I am trying to change the mouse cursor when it is within 200px of the bottom of each section. Although I used the code provided, it only seems to work for the first section. The e.pageY value is not being reset in subsequent s ...

What about connecting mapStateToProps with a specific ID?

Currently, I have a basic function that fetches all Elements const mapStateToProps = ({elements}) => { return { elements: getElementsByKeyName(elements, 'visibleElements'), }; }; I want to modify it to something like this c ...

display PHP JSON information using jQuery AJAX

I'm completely new to this subject. I have a Json result that looks like the following : { "span": " 1", "numcard": "12", "chan": " Yes", "idle": "Yes", "level": "idle ", "call": "No ", "name": "" } My goal is to ...

Screen content of a post request in Node.js

Can this code in node.js + express be simplified? // Code snippet for registering a new participant app.post('/api/participant', function (req, res, next) { var data = req.body; // Ensure only specific fields are uploaded var parti ...

Setting up an OnMouseOver event for each URL on a webpage

Is there a way to add an OnMouseOver event for all anchor tags on a page, without replacing any existing event handlers that are already in place? I'm looking for guidance on how to achieve this using JavaScript or JQuery. Any suggestions would be gr ...

The Optimal Approach for Importing Libraries across Multiple Files

I have two files - one containing the main code execution, and the other solely consisting of a class. For instance: File_1: const _ = require('underscore'), CoolClass = require('CoolClass'); _.map(//something) Files_2: const _ = ...

A step-by-step guide on how to fill a Vuetify select box with data retrieved from

I'm currently working on populating a select box in Vuetify by retrieving data through an ajax call. I'm struggling to figure out how to populate the select box with this data. The ajax call is successful and I receive an array of objects which I ...

Display the header on every single page using puppeteer

            Whenever I enable displayHeaderFooter, the header does not display. It only works if I add margin to @page in my CSS, but this causes the page height to increase by the margin value and content to overflow beyond the page boundaries. Is ...

Establishing global Kendo UI Window settings for all instances

I have been working extensively with Kendo UI windows and I am curious if there is a way to set default values on a global level. Alternatively, could I establish a parent window with predefined values and then selectively override the ones I want to chang ...

Angular offers the ability to implement various filter options such as selecting, using checkboxes, and displaying results

I recently came across some code that I need help with. The code snippet can be found here: https://jsfiddle.net/Dimetrius/58917Ldt/ I am looking to implement filtering by select and checkbox options, followed by displaying the result upon clicking a butt ...

Dynamic options can now be accessed and modified using newly computed getters and setters

When using Vuex with Vue components, handling static fields that are editable is easily done through computed properties: computed: { text: { get() { return ... }, set(value) { this.$store.commit... }, }, }, <input type ...

Tips for circumventing the need for setTimeout when managing the DOM in AngularJS

In my current project, I am utilizing a single dataset to populate items dynamically. The data population process is working correctly without any issues. However, once the data is populated, I encounter difficulties performing DOM operations without relyi ...

Detecting Browser Window Width Dynamically [JavaScript]

I want to create a dynamic variable that updates automatically as the browser window is resized in pixels. I need this variable to change without needing the page to refresh, and I don't want it written in the HTML document as it's used further d ...

The React data editor Dialog closes when the drop-down is clicked without triggering any onChange events

Utilizing the react-datasheet component, I have implemented a table to display a matrix/grid of data. To enhance user experience, I customized the dataEditor to launch a custom dialog where users can only choose from preselected values in a material-ui dro ...

The status of Angular $http request is (-1)

When using AngularJS to call a backend service or resource with the $HTTP GET method, if the service is not available it typically returns a 404 error. In Chrome's Network tab, this error would be displayed as: Request Method:OPTIONS Status C ...

Failed network request in my ReactJS project under the "Auth/network-request-failed" error code

I'm currently working on a project focused on learning to use react-router-dom and firebase authentication for user sign-in and sign-up. However, I've run into an issue where I keep getting a FirebaseError: "Firebase: Error (auth/network-request- ...

The customer opts to store all images indefinitely into the data stream

I have set up a node server that captures images from a webcam at regular intervals and sends them to the client using the Delivery.js node module. Upon monitoring the browser resources in Chrome development tools, it appears that each image sent is being ...

The Angular directive ng-if does not function properly when trying to evaluate if array[0] is equal to the string value 'Value'

In my code, I want to ensure that the icon is only visible if the value at array index 0 is equal to 'Value': HTML <ion-icon *ngIf="allFamily[0] === 'Value'" class="checkas" name="checkmark"></ion-icon> TS allFamily = [ ...