this
调用匿名函数时不会引用当前对象,因为它不遵循在作用域中设置的模式,obj.func()
并且不受其他方式的约束。相反,它指的是全局窗口对象(或在严格模式下)。this
func
obj
undefined
call
,apply
并且bind
没有帮助,因为store
尚未定义对象,因此没有对象可以作为thisArg
参数提供。另一方面, with store.revert
,this
指store
的是它被调用的时间并按预期运行。
该示例似乎过于做作,因为没有明显的动机将设置masterData
作为也设置的匿名函数的副作用data
。看来您可以执行以下操作:
// 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);
一般来说,如果一个模式看起来很难应用,它通常是不必要的,或者是实现预期结果的次优方式。OP 提出的data
IIFE setter 打破了经验法则:它没有单一的职责,并通过改变对象而产生副作用。
现在,假设您在定义此属性时确实需要this
从IIFE访问(或者对于确实有正当动机的未来读者),有多种方法可以实现这一点。
最明显和直接的解决方案是创建store
对象,然后添加数据并在第二步中对其进行变异:
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);
如果你不喜欢这两个步骤,你可以把它扔进 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);
另一种方法是使用此处所示的构造函数并调用它new
,使您可以访问this
上下文。
您正在使用的 IIFE 可能是一个完全独立的函数,它接受一个对象作为参数并改变它的两个属性,但这只是为了完整性而提及;它可能仅在您计划为多个对象重用该函数时才有用,在这种情况下,您不妨创建一个成熟的类或非 IIFE 构造函数。