最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

scope - Isolated execution context in JavaScript - Stack Overflow

programmeradmin3浏览0评论

I'm trying to execute a piece of code within an empty isolated execution context in JavaScript. In the below sample, I'm trying isolate isolated execution scope. What I want to do is to execute a function in context where no global variables are in.

(function() {
  'use strict';

  var scope = Object.create(null);
  var isolated = function() {
    'use strict';
    console.log(document); // Trying to get undefined
                           // but traces `document`.
  };

  isolated.call(scope);
})();

I thought it was simple to nullify global variables but there are too many!

var isolated = function(window, document, location /* etc */) {
  // ...
};

isolated.call(scope, undefined, undefined, undefined /* etc */);

Is there a better way to do this?

I'm trying to execute a piece of code within an empty isolated execution context in JavaScript. In the below sample, I'm trying isolate isolated execution scope. What I want to do is to execute a function in context where no global variables are in.

(function() {
  'use strict';

  var scope = Object.create(null);
  var isolated = function() {
    'use strict';
    console.log(document); // Trying to get undefined
                           // but traces `document`.
  };

  isolated.call(scope);
})();

I thought it was simple to nullify global variables but there are too many!

var isolated = function(window, document, location /* etc */) {
  // ...
};

isolated.call(scope, undefined, undefined, undefined /* etc */);

Is there a better way to do this?

Share Improve this question asked Jan 9, 2014 at 9:08 FlorentFlorent 12.4k10 gold badges50 silver badges58 bronze badges 2
  • How about using web workers? developer.mozilla/en-US/docs/Web/API/Web_Workers_API/… – gautam1168 Commented Sep 23, 2019 at 14:34
  • I found a way in EcmaScript 6 to adjust with(context) { ... }, so that any new variables we assign will go into the context object, not the global / window object. More info here: stackoverflow./a/62350258/218294 – Sam Watkins Commented Jun 12, 2020 at 18:26
Add a ment  | 

3 Answers 3

Reset to default 4

There is no good way to do this within javascript itself (but see Gareth Hayes answer for another option).

There are a couple of bad ways.

(function() {
  var scope = Object.create(null);
  var obscurer = {};
  for (var key in this) {
     obscurer[key] = undefined;
  }

  with (obscurer) {
    var isolated = function() {
      'use strict';
      console.log(document);
    };
  }

  isolated.call(scope);
})();

Note that you'll actually get an error because console is not defined rather than document, although you can fix this by not blocking 'console' in the obscurer object. You'll probably find that you need a whole bunch more globals than you realised.

You're also only blocking the enumerable properties of window. If you bee aware of nonenumerable properties that you want to block too, you'll have to add those to obscurer.

Of course, using with means you can't use strict mode any more as well, and everyone will look down their noses at you..

There are more interesting options available if you are working within node rather than the browser.

Use my MentalJS parser to isolate the environment. You can then choose which objects/variables it has access to by customizing the code.

http://businessinfo.co.uk/labs/MentalJS/MentalJS.html

http://code.google./p/mentaljs/

By default it allows access to document but you can prevent this, customize the environment here http://code.google./p/mentaljs/source/browse/trunk/MentalJS/javascript/Mental.js#260 you can then choose if they have access to Math etc.

It can be done without ECMA6 by using an IIFE that contains your trusted-needs-protection code, into which you inject your untrusted-needs-isolation-code (see example).

(function(injectedFunction) {
    /* Trusted code, that needs protection from untrusted code access */
    var hostingFuncPrivatePrimitive = "Hello there";
    var hostingFuncPrivateObject = {
        this_is_mine: true
    };

    var sharedPrimitive = 'This is shared';
    var sharedObject = {};

    // Running the untrusted code:
    injectedFunction(sharedPrimitive, sharedObject);

    console.log("sharedObject is: " + JSON.stringify(sharedObject));
    console.log("hostingFuncPrivateObject is: " +
        JSON.stringify(hostingFuncPrivateObject));
})(

(function(primitiveArg, objArg) {
    /* Untrusted code that needs isolation */

    // 1. using primitive (legal)
    console.log('primitiveArg is: ' + primitiveArg);

    // 2. Writing value to given objArg (legal):
    objArg.mumu = 'mimi';

    // 3. Trying to access host function variables (illegal)
    try {
        console.log('hostingFuncPrivatePrimitive is:' +
            hostingFuncPrivatePrimitive);
        hostingFuncPrivateObject.this_is_mine = false;
    } catch (e) {
        console.log(e);
    }
})

);

If you place the above in Chrome's console, you will get:

    primitiveArg is: This is shared
    VM117:29 ReferenceError: hostingFuncPrivatePrimitive is not defined
            at <anonymous>:26:17
            at <anonymous>:11:5
            at <anonymous>:16:3
    VM117:12 sharedObject is: {"mumu":"mimi"}
    VM117:13 hostingFuncPrivateObject is: {"this_is_mine":true}

P.S.: I know I'm late to the party, but maybe this helps anybody.

发布评论

评论列表(0)

  1. 暂无评论