Struggling with understanding the JavaScript bind method?

After running the JavaScript script provided below, I noticed that the output of func2() is foobar instead of George. Can someone shed some light on why using func2 = func.bind(someuser) does not bind someuser to func?

var someuser = {
    name: 'George',
    func: function () {
        console.log(this.name);
    }
};
var foo = {
    name: 'foobar'
};
func = someuser.func.bind(foo);
func(); // Output will be foobar
func2 = func.bind(someuser);
func2(); // Expected output should be George, but it's actually foobar

Answer №1

According to information sourced from MDN:

The bind() method generates a new function (referred to as a bound function) with the identical function body (internally denoted as "Call" attribute in ECMAScript 5 terms) as the function it is invoked upon (the target function of the bound function), where the this value is linked to the first argument of bind(), without the possibility for override.

To put it simply, attempting to use bind on an already bound function is not permissible.

In your specific scenario, you will need to execute the following:

func2 = someuser.func.bind(someuser);

Answer №2

To achieve the desired outcome, you may consider utilizing a weak binding technique:

function createWeakBinding(func, object) {
    var GLOBAL = this;

    return function () {
        return func.apply(this === GLOBAL ? object : this, arguments);
    };
}

With this approach, you can implement the following functionality:

var user = {
    name: 'John',
    action: function () {
        console.log(this.name);
    }
};

var details = {
    name: 'details'
};

var actionFunc = createWeakBinding(user.action, details);
actionFunc(); // output details

var actionFunc2 = createWeakBinding(actionFunc, user);
actionFunc2(); //output John

Explore the demo here: http://jsfiddle.net/E98GF/


The issue with traditional binding is that it locks the object assigned to the this keyword, making it difficult to change. By employing weak binding, we check if the this object refers to the GLOBAL object (defaulting to a specific context if not). This allows for more flexibility in defining the execution context.


Alternatively, a simpler solution in your scenario would be:

var user = {
    name: 'John',
    action: function () {
        console.log(this.name);
    }
};

var details = {
    name: 'details'
};

var actionFunc = user.action.bind(details);
actionFunc(); // output details

var actionFunc2 = user.action.bind(user);
actionFunc2(); //output John

Using bind directly improves code readability and ensures that calling actionFunc2 triggers user.action immediately without an intermediate step.

Answer №3

You have already linked the function someuser.func.

You may need to configure the script in a different way.

Alternatively, you can do:

func = someuser.func.bind(foo);
func(); // will display foobar
func2 = someuser.func.bind(someuser);
func2(); //will display foobar

Avoid attempting to rebind a function that is already bound.

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

Accept only hexadecimal color codes as user input

How can I create a variable in JavaScript that only accepts color codes such as rgba, hashcode, and rgb? I need a solution specifically in javascript. ...

During operation, invoking the next-auth function Signout() in production will direct the user to "localhost:3000" regardless of whether a callbackUrl is provided

After successfully deploying my Next.js app to AWS Amplify and setting up my environment variables correctly (including APP_URL and NEXTAUTH_URL, which are the same), I encountered an issue when attempting to sign out using credentials from MongoDB Atlas. ...

Relocating scripts that have already been loaded

When using AJAX to load a page, the entire content including <html>, <head>, <body> is loaded. This means that all scripts meant to run on page load will be called. However, sometimes the browser may remember that certain scripts have alr ...

Exploring Angularjs: Navigating to a particular element within ng-repeat

I created a custom directive that generates a list of buttons using ng-repeat: HTML <div ng-controller="toggleButtonController" ng-init="init()" id="parent"> <div ng-repeat="btn in setting" style="display:inline"> <button class ...

Warning in Google Script editor

Currently, I am working on creating some quick scripts to manipulate spreadsheets in my Google Drive. However, I am cautious about the script unintentionally running and making changes to data before I am ready or executing multiple times after completing ...

What is the best way to eliminate an object from an array using JavaScript?

I am currently working with two arrays named totalArray and selectionArray. These arrays have dynamic values, but for the sake of example I have provided sample arrays below. My goal is to remove objects from totalArray based on their id rather than inde ...

Animating elements on a webpage can be achieved by using both

Is there a way to create an animation that moves objects based on button clicks? For example, when the "Monday" button is pressed, the object with the correct color will move down. If any other button like "Tuesday" is clicked, the previous object will mov ...

Adding information to a MySQL database using a variable - What's the best way?

When I attempt to insert values defined in JavaScript at the beginning of the program, it seems to have an issue with me trying to input variables. Instead, it requires me to enter the raw name. The error message displayed is as follows: Error: ER_BAD_FI ...

Search the database to retrieve a specific value from a multi-dimensional array

My database is structured as shown in the image below: https://i.sstatic.net/Flne8.png I am attempting to retrieve tasks assigned to a specific user named "Ricardo Meireles" using the code snippet below: const getTasksByEmployee = async () => { se ...

JavaScript implementation of Ancient Egyptian Multiplication using PHP code

Let's dive into the algorithm. If we have two integers, A and B (remember, only integers), that need to be multiplied, here is how it works: we continuously multiply A by 2 and divide B by 2 until B cannot be divided any further, or in other words, un ...

Substitution of "with" operator in strict mode

Let's say I have a user-entered string value stored in the variable f. For example: f = "1/log(x)"; In vanilla JavaScript, I used the following operator: f = "with (Math) {" + f + "}"; While this code worked perfectly fine in vanilla javascript, i ...

Changing the anchor tags within a string and returning the modified string using a JavaScript function

When retrieving string data from a CMS, I noticed it contains anchor links that need to be modified. For my app built using the Ionic Framework, I want to add an onClick function to these "a" tags to utilize the "inappbrowser" Cordova plugin. To do this, ...

The <span> tag with content-editable attribute loses selection when the mouse button is released

I'm attempting to utilize a content-editable span tag as an inline text input box with variable width. Everything is functioning properly, except for the issue of not being able to select the entire text when focusing on the box. When tabbing to the e ...

Express server failing to serve js and css files

Currently, I'm working on a ReactJS project with React Router implemented. When attempting to access /dashboard/stream, the server is returning the index.html file successfully. However, there are 301 errors for the CSS and JS files, resulting in noth ...

Employing the html.validationmessagefor to display a client-side error notification

My text fields have server-side validation messages. The field 'title' is a required field on the server side with a '[Required]' data attribute in the class, but it only seems to be checked on a postback or form submit. I am saving the ...

The comparison between exposing and creating objects in a Nodejs router file

Recently, I began using expressjs 4.0.0 and was impressed by the express.Router() object. However, a dilemma arose when I moved all my routes to another file - how do I expose an object to the routes file? In my server.js file: ... var passport = ...

Tips for preventing countdown from resetting when you refresh the page

I'm currently using a countdown feature on my Shopify website that is functioning well, except for one issue - whenever the page is refreshed, the countdown resets itself. Can anyone provide guidance on how to solve this problem? Thank you in advance! ...

What is the best way to fill a "multiselect" element with information from a JSON object?

I'm struggling to populate the multiselect field with data from a JSON object. No matter which multiselect I use, the data shows in inspect mode but not on the frontend. It was supposed to look like this. https://i.sstatic.net/FVz2H.png but it comes ...

Using the Javascript function getElementById to retrieve user input for passing a RSS FeedURL

I've been working on creating a basic form where users can input a Feed URL and see the contents displayed on the HTML page. For testing purposes, I have used "https://jquery-plugins.net/rss" as the feedUrl, and it has been functioning normally. This ...

When passing req.body to another function, it returns as undefined

Here is an example of the code: SaleComponent.html <form class="form-horizontal" #salesdetails="ngForm" (ngSubmit)="onSubmit(salesdetails.value)"> <div class="form-group" *ngFor="let label of labels"> <label for="it ...