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

Ref: http://www.objectplayground.com/

Keys:

  • 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

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

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

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;
}

Last updated