Trying to get the following code to work; As the store variable is assigned an anonymous object, the "data" property is populated using a function call. This setting should also set the contents of the other object's property "masterData". I expected the "this" keyword to refer to the anonymous object being created, but I'm wrong...
var store = {
masterData : [],
revert: function() {
this.data = shallowCopy(this.masterData);
},
data: (function() {
var overviewData = getOverviewData();
this.masterData = overviewData;
return chartData;
}).call(),
};
See also that "revert" property; It's given a function that'll create a copy of the object's data property contents.
What should be used, since "this" returns the DOMWindow object?
Trying to get the following code to work; As the store variable is assigned an anonymous object, the "data" property is populated using a function call. This setting should also set the contents of the other object's property "masterData". I expected the "this" keyword to refer to the anonymous object being created, but I'm wrong...
var store = {
masterData : [],
revert: function() {
this.data = shallowCopy(this.masterData);
},
data: (function() {
var overviewData = getOverviewData();
this.masterData = overviewData;
return chartData;
}).call(),
};
See also that "revert" property; It's given a function that'll create a copy of the object's data property contents.
What should be used, since "this" returns the DOMWindow object?
Share Improve this question asked Apr 26, 2012 at 10:31 JemJem 6,42614 gold badges58 silver badges75 bronze badges4 Answers
Reset to default 3The data
function is being called before the object is defined; this
will not be an alias to an object prior to that object's ing into existence. You can use a constructor function with a private, short-lived variable:
var getOverviewData = function () { return "I'm overview data!" }
var chartData = "I'm chart data!"
var store = new function () {
var _masterData
this.revert = function() {
this.data = shallowCopy(this.masterData)
}
this.data = (function() {
_masterData = getOverviewData()
return chartData
}).call()
this.masterData = _masterData
}()
console.log(store)
// { revert: [Function],
// data: 'I\'m chart data!',
// masterData: 'I\'m overview data!' }
i have the same problem and i solved it by just sending the scope with the function.
var self = this;
setInterval( yourFunction(self), 1000);
yourFunction:function( self )
{
console.log(this);
console.log(self);
}
you see when it logs "this" it refers to the DOM and the self is refering to where ever you came from. i hope this helps! :)
EDIT: instead of inside Data to set the masterData, set the Master data after the Data is created.
var store = {
masterData : [],
revert: function() {
this.data = shallowCopy(this.masterData); //Here is where you create data
masterData = this.data.overviewData; //set the masterData
},
data: (function() {
var overviewData = getOverviewData();
return chartData;
}).call(),
};
i think this should work, otherwise sorry :)
change the flolowing line
}).call(),
to
})()
or, if you really want to use the call
method :
}).call(store)
this
won't refer to the current object when the anonymous function is called because it doesn't follow the obj.func()
pattern which sets this
in the func
scope to obj
and is not bound by some other means. Instead, it refers to the global window object (or undefined
in strict mode).
call
, apply
and bind
don't help since the store
object hasn't been defined yet so there's no object to give as a thisArg
parameter. On the other hand, with store.revert
, this
refers to store
by the time it's called and behaves as expected.
The example seems overly contrived because there's no obvious motivation for setting masterData
as a side effect of the anonymous function that also sets data
. It seems you could just do something like:
// some sameple funcs and data for testing purposes
var getOverviewData = function () { return [42]; };
var shallowCopy = function (a) { return a.slice(); };
var chartData = [24];
var store = {
masterData: getOverviewData(),
revert: function () {
this.data = shallowCopy(this.masterData);
},
data: chartData,
};
console.log(store.data);
store.revert();
console.log(store.data);
In general, if a pattern seems awkward to apply, it's often unnecessary or is a suboptimal way to achieve the desired result. The data
IIFE setter proposed by OP breaks rules of thumb: it doesn't have single responsibility and causes a side effect by mutating an object.
Now, assuming you really do need to access this
from an IIFE while defining this property (or for future readers who do have a legitimate motivation), there are multiple ways to achieve this.
The most obvious and direct solution is to create the store
object and then add the data and mutate it in a second step:
var getOverviewData = function () { return [42]; };
var shallowCopy = function (a) { return a.slice(); };
var chartData = [24];
var store = {
masterData: [],
revert: function () {
this.data = shallowCopy(this.masterData);
},
};
store.data = (function () {
this.masterData = getOverviewData();
return chartData;
}).call(store);
console.log(store.data);
store.revert();
console.log(store.data);
If you don't like this as two steps, you can toss it in an IIFE:
var getOverviewData = function () { return [42]; };
var shallowCopy = function (a) { return a.slice(); };
var chartData = [24];
var store = (function () {
var store = {
masterData: [],
revert: function () {
this.data = shallowCopy(this.masterData);
},
};
store.data = (function () {
this.masterData = getOverviewData();
return chartData;
}).call(store);
return store;
})();
console.log(store.data);
store.revert();
console.log(store.data);
An alternative is using a constructor function as shown here and invoking it with new
which gives you access to the this
context.
The IIFE you're using could be a separate function entirely that accepts an object as a parameter and mutates the two properties on it but this is only mentioned for pleteness; it's probably only useful if you plan to reuse the function for multiple objects, in which case you might as well create a full-blown class or non-IIFE constructor function.