JSFiddle - React, Tailwind, and code Playground

by Jeremy Banks

HTML

<p>
    Chrome users must <q>Enable Experimental JavaScript</q> in <code>chrome://flags/</code> to run this example.
</p>

JavaScript

with(scope()) {
    currentScope.x = 10;
    
    console.log(x);              // 10
    console.log(currentScope.x); // 10
    console.log(parentScope);    // null
    
    var scopeB = scope(); // inheriting from currentScope by default
    
    scopeB.y = 20;

    with(scopeB) {
        console.log(x);              // 10
        console.log(currentScope.x); // 10
        console.log(parentScope.x);  // 10
        
        console.log(y);              // 20
        console.log(currentScope.y); // 20
        console.log(parentScope.y);  // undefined
        
        x = y;
        
        console.log(x);              // 20
        console.log(currentScope.x); // 20
        console.log(parentScope.x);  // 10
    }

    console.log(x);              // 10
    console.log(currentScope.x); // 10
    console.log(parentScope);    // null
}

// Creates an Object that uses the specified parent as the prototype,
// or else has no prototype. The new object will be given the properties
// `currentScope`, referring to itself, `parentScope`, referring to
// its prototype, and `scope`, a wrapper for this scope function which
// defaults to using the new Object instead of nothing as the prototype.
function scope(parent) {
    var parentScope = (parent != undefined) ? parent : null;
    var scopeObj = Object.create(parentScope);

    scopeObj.currentScope = scopeObj;
    scopeObj.parentScope = parentScope;
    scopeObj.scope = function(parent) {
        if (parent == null) {
            parent = scopeObj;
        }

        return scope(parent);
    }
    
    return scopeObj;
}