Skip to content
This repository has been archived by the owner on Feb 8, 2019. It is now read-only.

Not working bind function #2

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

snewcomer
Copy link
Contributor

@snewcomer snewcomer commented Dec 17, 2017

So leaving this here for discussion.

I came across a few issues relating to the context of this in an initializer function. I'm still digging in...

I did try as a method property as well. As a prototype property, the decorator function gets the prototype passed as an argument. So swapping out the desc.value with initializer doesn't affect the call order.

tc39/proposal-class-public-fields#34
babel/babel#6977
tc39/proposal-class-fields#62

}

@bind nextMe = () => {
return this.prop;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you put a debugger here, the context of this is the getter {enumerable: true, configurable: false, writable: true, initializer: ƒ}

@snewcomer
Copy link
Contributor Author

bind

@pzuraq
Copy link
Collaborator

pzuraq commented Dec 18, 2017

So extractValue is going to run an initializer if it exists. This allows us to get the value of the initializer (a class field) at class definition time instead of class run time.

Given this class:

class Foo {
  bar = 'baz';
}

It transpiles to something like this:

const FooInitializers = {
  bar() {
    return 'baz';
  }
}

class Foo {
  constructor() {
    for (let initializer in FooInitializers) {
      let initializerFunc = FooInitializers[initializer];

      this[initializer] = initializerFunc.apply(this);
    }
  }
}

This may seem odd, but it's actually much better for JS classes to always initialize values like class fields in the constructor. For one thing, new objects and arrays will always be created, so we don't shared object or array instances between classes.

For @binds use case, we need to pass in the instance of the class. So, for whatever value we are decorating, we want to transform the descriptor into this:

let descriptor = {
  writable: true,
  configurable: true,
  enumerable: true,
  
  initializer() {
    return run.bind(this, method);
  }
}

Where method is the extracted value of the original descriptor. The decorator utility function was not built to allow you to do this, so you'll need to figure out a different way to create the descriptor itself.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants