JavaScript,在匿名对象创建期间访问其他成员?

4
尝试让以下代码工作;由于store变量被分配了一个匿名对象,因此"data"属性是通过函数调用填充的。这个设置还应该设置其他对象属性"masterData"的内容。我期望"this"关键字指的是正在创建的匿名对象,但我错了...
    var store = {

        masterData : [],

        revert: function() {

            this.data = shallowCopy(this.masterData);
        },

        data: (function() {

            var overviewData = getOverviewData();
            this.masterData = overviewData;
            return chartData;

            }).call(),
    };

请看“还原”属性;它给出了一个函数,将创建对象数据属性内容的副本。
由于“this”返回DOMWindow对象,应该使用什么?
4个回答

3

data函数在对象定义之前被调用,因此this在对象生成之前不会成为对象的别名。您可以使用带有私有、短暂变量的构造函数:

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!' }

确实,有道理...我会相应地重构 :) - Jem

2
我有同样的问题,我通过将作用域与函数一起发送来解决它。
    var self = this;
    setInterval( yourFunction(self), 1000);

    yourFunction:function( self )
    {
        console.log(this);
        console.log(self);
    }

当它记录“this”时,它指的是DOM,而self指的是你来自哪里。希望这可以帮到你! :)

编辑: 不要在Data内设置masterData,而是在创建Data后设置Master数据。

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(),
};

我认为这应该可以工作,否则很抱歉 :)

嗨,感谢您的输入。这里的问题是获取指向正在创建的对象的指针。Data、revert和masterData是此匿名对象的三个成员。而且,data的定义需要访问“masterData”成员。 - Jem
1
我认为当你给数据一个引用(self)时,你可以这样说:self.masterdata = overviewData; (在这种情况下,“self”这个名称并不是很清晰哈哈) - Arjen van Heck
很遗憾,无法获取数据:(var me = this; function() { var overviewData = getOverviewData(); me.masterData = overviewData; return chartData; }).call(),:( - Jem
不错的尝试 :) 但我想这个解释就像Richard在下面另一个答案中提到的那样: "这不会是在该对象出现之前的对象的别名"。不管怎么样,谢谢! - Jem
self 这个概念并不真正起作用(即使它起作用时通常也是反模式)。在设置 data 的 IIFE 中,store 不存在,因此无法访问 this 来分配一个 self 变量。这增加了另一层间接性,但并不能避免 this(指 store)和 store 本身不存在的事实。我不确定 setInterval 应该做什么。第二个片段中的“解决方法”完全是不同的逻辑。 - ggorlen

1

更改以下行

}).call(),

})()

或者,如果你真的想使用call方法:

 }).call(store)

使用IIFE意味着thiswindow,并且在call(store)中未定义store - ggorlen

0

this在匿名函数被调用时不会引用当前对象,因为它不遵循obj.func()模式,该模式将this设置在func作用域中为obj并且不受其他方式的限制。相反,它引用全局窗口对象(或在严格模式下为undefined)。

call, applybind都无法帮助,因为store对象尚未定义,因此没有对象可作为thisArg参数提供。另一方面,使用store.revertthis在调用时指向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违反了经验法则:它没有单一职责,并通过改变对象而导致副作用。
现在,假设您确实需要在定义此属性时从IIFE访问this(或对于未来的读者确实有合理动机的情况),有多种方法可以实现这一点。
最明显和直接的解决方案是创建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可以是完全独立的函数,它接受一个对象作为参数并对其进行两个属性的变异,但这仅仅是为了完整性而提到的;如果您计划将该函数用于多个对象,则可能有用,否则最好创建一个完整的class或非IIFE构造函数。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接