5

I have this code...

function a(options) {
    for (var item in options) {
       if ( ! options.hasOwnProperty(item)) {
          continue;
       }
       this[item] = options[item];
    }
}

a({ 'abc': 'def' });

jsFiddle.

Whilst this unpacks variables from the object, it sets them to global scope (attached to window) because this is window in that circumstance.

So after the function I can do alert(abc) and it will alert def, which isn't good.

How would I set the scope of the variables to the function?

alex
  • 479,566
  • 201
  • 878
  • 984
  • I think the only possibility would be to use `with` but normally it should be avoided. – Felix Kling Mar 28 '11 at 00:59
  • @Felix Thanks, please post an answer :) – alex Mar 28 '11 at 01:02
  • possible duplicate of [Javascript local variable declare](http://stackoverflow.com/questions/1119335/javascript-local-variable-declare) – Jon Mar 28 '11 at 01:04
  • 1
    Like Felix said, you can use with, but I'm kinda curious why you would go through the trouble of unpacking that object into the function's scope. Couldn't you just use the options variable you passed in? – JWC Mar 28 '11 at 01:06
  • @Mrbuubuu I was answering [this question](http://stackoverflow.com/questions/5453121), and the concept intrigued me. – alex Mar 28 '11 at 01:14
  • @Jon Didn't find that one, I've cast my close vote as well. – alex Mar 28 '11 at 01:21
  • @Alex: what does this line do: if (!options.hasOwnProperty(item)) { continue; } – frenchie Mar 28 '11 at 01:42
  • @frenchie It ensures that if you have augmented the object, it won't iterate over other enumerable properties up the protoype chain. – alex Mar 28 '11 at 01:48
  • @frenchie Basically it stops (possible) unwanted side effects. – alex Mar 28 '11 at 03:19

2 Answers2

2

You can access the function from inside itself using the callee property:

function a(options) {
    var thiz = arguments.callee;
    for (var item in options) {
        if (!options.hasOwnProperty(item)) {
            continue;
        }
        thiz[item] = options[item];
    }
}

a({
    'abc': 'def'
});

alert(a.abc);

Alternatively, you can set the scope when you call it:

function a(options) {
    for (var item in options) {
        if (!options.hasOwnProperty(item)) {
            continue;
        }
        this[item] = options[item];
    }
}

a.call(a, {
    'abc': 'def'
});
alert(a.abc);
Evan Trimboli
  • 29,900
  • 6
  • 45
  • 66
2

If you want to put the properties of the object in the scope of the function, you can extend the scope by using with:

function a(options) {
    with(options) {
        // properties of `options` are in the scope
        alert(abc);
    }
}

Disclaimer: Make sure you read the documentation and about disadvantages of with. It should be avoided and is also kind of deprecated:

Using with is not recommended, and is forbidden in ECMAScript 5 strict mode. The recommended alternative is to assign the object whose properties you want to access to a temporary variable.

So the questions is why not stick with options ?

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143