8

私は通常、グローバル スコープを、常にどこからでもアクセスできる名前空間と考えています。グローバル スコープを完全に非表示にすることが理論的に可能かどうかを知りたいです。たとえば、eval(ブラウザのコンソールで) 実行したいコードがあるとします。

var code = 
  "console.log(this);   " + // access the global object directly
  "console.log(window); " + // access the global object as the window object
  "newGlobalVar = 42;   ";  // implicitly create global object
eval(code);

eval呼び出しをthisラップすることにより、次windowから非表示にすることができますcode

(function (window) { eval(code); }).call({});

しかし、code暗黙的にグローバル変数を作成することを止めることはできません。なんとなく可能ですか?私はこのようなものを使用したくありません, 私はただ興味があります.

4

3 に答える 3

5

注: これはまだ進行中の作業であり、一部は squint のコード スニペットに触発されています。

function quarantinedFunction(fnText){
    var exceptionKeys=[
        "eval","Object",  //need exceptions for this else error. (ie, 'Exception: redefining eval is deprecated')
        "Number","String","Boolean","RegExp","JSON","Date",
    ];
    var forbiddenKeys=[
        "fn","fnText","forbiddenKeys","exceptionKeys","empty","oForbiddenKeys",
    ];
    var oForbiddenKeys=Object.create(null);
    var empty=Object.create(null);
    Object.freeze(empty);
    forbiddenKeys.forEach(function(key){
        oForbiddenKeys[key]=null;
    });
    [this,self].forEach(function(obj){
        Object.getOwnPropertyNames(obj).forEach(function(key){
            if(!key.match(/^[\$\w]+$/))return;
            oForbiddenKeys[key]=null;
        });
    });
    exceptionKeys.forEach(function(key){
        delete oForbiddenKeys[key];
    });

    if(0){//debugging.
        return function(){
            return Object.keys(oForbiddenKeys);
            return Object.keys(empty);
        };
    }

    fnText=[
        '"use strict";',
        "var "+Object.keys(oForbiddenKeys).join(", ")+";",
        "{",
        fnText,
        "}"
    ].join("\n");

    var fn= (function(){
        with(empty)
        {
            return new Function("self","window",fnText);
        }
    })();

    return function(){
       return fn.call(Object.create(null));      //self,window undefined
       return fn.call(empty,empty,empty);  //self,window are objects w/o properties
    };
}

出力結果 (Firefox スクラッチパッドから):

quarantinedFunction("return location.href;")();
/*
Exception: location is undefined
*/
quarantinedFunction("someGlobalVar=15;")();
/*
Exception: assignment to undeclared variable someGlobalVar
*/
quarantinedFunction("return 9*9;")();
/*
81
*/
quarantinedFunction("return console;")();
/*
undefined
*/

そして、いくつかの結果を持つjsfiddle

注: いくつかの予期しない結果がフィドルに表示されますが、他のツールには表示されません (つまり、location変数は、フィドルが Firefox オーロラから表示されたときにページの URL を返しますが、クロムやスクラッチパッド devtool では表示されません。おそらく Firefox__noSuchMethod__または類似のものの手仕事によるものです)。アクセスされたときにのみプロパティが追加される「遅延バインディング」メカニズム)。

于 2013-05-30T00:57:07.133 に答える