Alexey_js
Alexey_js

Reputation: 77

Programming bind in js

I have decided to recreate Function.prototype.bind as binding in order to exercise. Woefully, I have encountered some problems and can't understand the reason of undefined output. Here is my code:

var alex = {
  firstname: "alex",
  surname: "surname",
}
let nameyourself = function() {
  console.log(`${this.firstname} ${this.surname}`);
}


Function.prototype.binding = function(smth, ...params) {
  smth.__proto__.bindedfunct = this;

  return smth.bindedfunct;

}
nameyourself.binding(alex)();

Why is this happening?

Upvotes: 1

Views: 73

Answers (2)

Peter Seliger
Peter Seliger

Reputation: 13366

A more detailed explanation is given beneath the example code.

const alex = {
  firstname: "Alex",
  surname: "Surname",
}

function nameYourself(...args) {
  console.log(`${this.firstname} ${this.surname}`);
  console.log('args : ', args);
}

Function.prototype.binding = function(target, ...boundArgs) {

  // the function to be bound.
  const boundFunction = this;

  // the binding wrapper-function.
  return function (...args) {
  
    // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/apply
    boundFunction.apply(target, [...boundArgs, ...args])
  }
}

nameYourself.binding(alex, 'Hello')(alex.firstname, alex.surname);
.as-console-wrapper { max-height: 100%!important; top: 0; }

Since the custom bind functionality binding should be implemented via Function.prototype it will be called itself as a method of every function object. Thus, a binding's this context will be a function.

The latter then shall be executed within a custom this context. For the OP's example this context is intended to be the target object alex.

In order to achieve the OP's task the binding implementation needs to return a wrapper function that inside its function body does delegate the bound function to the target object via a functions apply method.

Upvotes: 1

Moritz Roessler
Moritz Roessler

Reputation: 8611

Your function binding doesn't do what you expect. You're just returning the function you pass it.

In order to achieve a similar functionality as bind you need to use Function.prototype.call/apply to call the function with a thisBinding.

Here's a sample implementation using .apply;

var alex={
    name:"alex",
    surname:"surname",
}
let nameyourself = function(){
   console.log(`${this.name} ${this.surname}`);
}

Function.prototype.binding = function (thisBinding, ...args) {
    return (..._args) => {
        this.apply(thisBinding, [...args, ..._args]);
    }
}

nameyourself.binding(alex)()

Upvotes: 3

Related Questions