In this post, the author is using:
$.fn.wPaint = function(settings) {
settings = $.extend({}, defaultSettings, settings || {});
Q: Wouldn't that overwrite the settings variable the calling scope? I would think you'd want to create a new variable, which would mean that you'd have a total of 3 variables:
- The Default settings in the closure scope
- The settings in the arguments
- The settings in the local scope
5 Answers 5
Objects are always passed by reference.
In your code, you're just say that the local variable settings will point to a different objects. So you pass the object by reference then you said "ok, I'm not interested in that reference anymore, point to that other object".
To be clear, if you have:
var a = {foo: "bar"};
var b = a;
b = {bar: "foo"};
You're not "destroying" neither "change" the original object {foo: "bar"}. You just point b to a different object, a will still point to the original one, so won't be affected.
It's the same in your scenario.
Comments
The settings argument is a reference to a variable in the calling scope. Inside your function you are assigning a new object to the settings variable, this breaks the reference and points the local variable to a new value in the local scope. If you modified settings, without assigning to it, it would affect the settings in the calling scope. The settings in the arguments is the settings in the local scope.
6 Comments
settings = you will break any reference settings has to another object.var defined within it. Aside from the values they're given, they have no ties to calling scope.In JavaScript, all arguments are passed "by value." The key is that, in the case of settings, the value is a reference.
This is not the same as "by reference." It can be similar as you are still referencing the same object in memory:
$.fn.wPaint = function(settings) {
settings.foo = 'foo'; // updates object in calling scope
// etc.
};
But, changing settings itself only changes its own value to a new reference:
$.fn.wPaint = function(settings) {
settings = $.extend(...);
};
1 Comment
If you want to do this you'll need to pass setting inside an object {}.
$.fn.wPaint = function(settingsContainer) {
settingsContainer.settings = $.extend({}, defaultSettings, settings || {});
-
var settingsContainer = {settings:originalSettings};
$.fn.wPaint(settingsContainer);
originalSettings = settingsContainer.settings;
1 Comment
You could pass the settings object as the first argument to the function $.extend:
$.fn.wPaint = function(settings) {
$.extend(settings, defaultSettings, settings || {});
}
See this example http://jsfiddle.net/26Bst/ and read the API entry for more details.
4 Comments
console.log on the script execution flow? Could you provide a jsFiddle for that?console.log(obj) is logging the reference to the object, not a copy of its state on that particular moment (in this case, on your first call to the function). By the end of the execution, the Object contains three values, this is why you see the same output on both calls.