> For the complete documentation index, see [llms.txt](https://notes.lirenxn.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://notes.lirenxn.com/2020/notes-03-31-reactcontext-js-inherit.md).

# Notes-03-31-ReactContext-JS-inherit

### React Context

* `React.creatContext()` is called only once, `multiple context objects` is handled by `Provider` call
* `<Context.Provider>` will create a `new instance` internally in the Context and separate it with other `Provider` from the same `Context` object
* `useContext`/`<Context.Consumer>` grab the closest `Provider` and consumer its value only

### Javascript inheritance in ES5 <a href="#javascript-inheritancees5" id="javascript-inheritancees5"></a>

**Ref:** <http://www.objectplayground.com/>

#### Keys: <a href="#keys" id="keys"></a>

* use `Object.create()` to create new object as prototype
* set `Child.prototype` to inherit (extends)
* reset `Child.prototype.constructor` to keep correct constructor
* use `Parent()` WITHOUT `new` as `super()`
* `Object.getPrototypeOf()` to properly find prototype

#### Proper inheritance <a href="#proper-inheritance" id="proper-inheritance"></a>

```javascript
function Base(name, group){
  this.name = name;
  this.group = group;
}

// To define public inheritable function
Base.prototype.getPath = function (){
  return this.group + '.' + this.name;
}

function Future(init, opt, extra){
  this.resolved = undefined;
  // To keep `this` in `done()` function
  const self = this;
  function done(v){
    self.resolved = v;
  }
  if(opt){
    // To pass the correct 'this' to `super()`
    Base.call(self, opt.name, opt.group);
  }
  init(done, ...extra);
}

// To inherit properly with correct constructor
Future.prototype = Object.create(Base.prototype);
Future.prototype.constructor = Future;

// To define public inheritable function
Future.prototype.then = function(cb){
  this.resolved = cb(this.resolved) || this.resolved;
}

function RejectableFuture(init, opt){
  this.rejected = undefined;
  // To keep `this` in `done()` function
  const self = this;
  function wrong(v){
    self.rejected = v;
  }
  // To pass the correct 'this' to `super()`
  Future.call(self, init, opt, [wrong]);
}

// To inherit properly with correct constructor
RejectableFuture.prototype = Object.create(Future.prototype);
RejectableFuture.prototype.constructor = RejectableFuture;

// To define public inheritable function
RejectableFuture.prototype.catch = function(cb){
  try{
    this.resolved = cb(this.rejected) || this.resolved;
  }catch(rejected){
    this.rejected = rejected;
  }
}

// To overwrite parent function
RejectableFuture.prototype.then = function(cb){
  try{
    this.resolved = cb(this.resolved) || this.resolved;
  }catch(rejected){
    this.rejected = rejected;
  }
}

rft = new RejectableFuture(
  (done, wrong) => {
    console.log('done n wrong');
    done(1);
    wrong(2)
  }, 
  { 
    name:'doneNwrong', 
    group:'ulti' 
  }
);

rft.then(console.log);
// 1
rft.catch(console.log)
// 2
rft.then(r => { console.log(r); return `return(${r})`; });
// 1
rft.then(console.log);
// return(1)
rft.catch(r => { console.log(r); throw `throw(${r})`; });
// 2
rft.catch(console.log);
// throw(2)
rft.getPath();
// ulti.doneNwrong
```

**The protorype chain**

```javascript
RejectableFuture.prototype === Object.getPrototypeOf(rft);
// Future {constructor: RejectableFuture, catch, then }

Future.prototype !== Object.getPrototypeOf(Object.getPrototypeOf(rft));
// Base {constructor: Future, then}

Future.prototype !== Object.getPrototypeOf(Object.getPrototypeOf(Object.getPrototypeOf(rft)));
// { constructot: Base, getPath }
```

**Use Prototype public function in constructor**

This is similar to react component constructor handler binding

```javascript
function Future(init, opt, extra){
  this.resolved = undefined;
  if(opt){
    Base.call(this, opt.name, opt.group);
  }
  // To use the public function, while bind is required
  init(this.done.bind(this), ...extra);
}

Future.prototype = Object.create(Base.prototype);
Future.prototype.constructor = Future;

Future.prototype.then = function(cb){
  this.resolved = cb(this.resolved) || this.resolved;
}

Future.prototype.done = function done(v){
  this.resolved = v;
}
```
