JSFiddle - React, Tailwind, and code Playground

by Alex Zolotyh

HTML

<h1>Смотри в консоль</h1>

Babel + JSX

var context = null;

class Context {
	constructor(parentContext){
		let context;

		if(parentContext){
    	// Создаем копию
			context = Object.create(parentContext)
			context.parent = parentContext;
		} else {
    	// Возвращаем текущий контекст
			context = this;
		}
		return context;
	}

	fork() {
  	// Возвращаем копию
		return new Context(this);
	}

	bind(fn) {
  	// Получем текущий контекст
		const context = this.fork();
    // Возвращаем функцию в которой уже замкнут контекст
		return () => {
			return context.run(() => fn.apply(this, arguments) , this, arguments);
		}
	}

	run(fn) {
  	// Заменяем текущий контекст на наш
		let  oldContext = context;
		context = this;
		const result = fn.call() // Выполняем функцию в контексте
		context = oldContext; // Возвращаем все как было
		return result; // Результат выполнения
	}
}

context = new Context();

var nativeSetTimeout = window.setTimeout; // Подменяем setTimeout

context.setTimeout = (callback, time) => {
	callback = context.bind(callback);
	return nativeSetTimeout.call(window, callback.bind(context), time);
};

window.setTimeout = function (){
	return context.setTimeout.apply(this, arguments);
};


context.fork({}).run(() => {
	context.message = 'Привет!';
	setTimeout(() => {
		console.log(`%cСообщение в контексте: ${context.message}`, 'font-size: x-large');
	}, 0);
});

console.log(`%cСообщение вне контекста: ${context.message}`,'font-size: x-large');