JSFiddle - React, Tailwind, and code Playground

by Jeremy Banks

HTML

<p>
    Supported in in Firefox. Chrome users must <q>Enable Experimental JavaScript</q> in <code>chrome://flags/</code>.
</p>

<p>
    Remember that the <code>with</code> statement is disabled in strict mode and that the JITs may hate this code.
</p>

JavaScript

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

    with(scopeB) {
        console.log(currentScope === scopeB); // true
        
        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;
}