从同一对象内部访问对象内部的数组

时间:2018-06-16 16:45:33

标签: javascript arrays object

我以前做过类似的事情,但我无法让它发挥作用。

我运行它并获得“无法读取属性'0'或未定义...”

(randomResult()函数从传递的数组中返回一个随机元素,并在其他地方正常工作。)

var objectOfArrays = {
  array1: ["apple","orange","pear","mango"],
  array2: [
    "I want no fruit!",
    "I will have one " + randomResult(this.array1) + "."
  ]
}

console.log(randomResult(objectOfArrays.array2));

2 个答案:

答案 0 :(得分:2)

对象尚未定义,您不能在对象声明中使用this

要清楚,就像那样:

const obj = {
  a: 1,
  b: this.a,
  c: obj.a
}

无效,bc无法访问当前声明的对象。

但是,如果您延迟访问权限,那么它将起作用:

const objectOfArrays = {
  array1: ["apple","orange","pear","mango"],
  get array2() {
    return [
      "I want no fruit!",
      "I will have one " + randomResult(this.array1) + "."
    ]
  }
}

只有在您尝试访问objectOfArrays.array2时才会执行getter代码。但请记住两件事:首先,它将是只读的:如果您还要设置道具array2,您还必须创建setter。其次,更重要的是,通过这种方式,每次访问array2时都会执行getter,因此返回一个新数组 - 来自array1的新随机结果。如果要返回相同的内容,则必须将结果缓存在某处:

const objectOfArrays = {
  array1: ["apple","orange","pear","mango"],
  _array2: null, // this could be actually omitted, see `Symbol` example
  get array2() {
    return this._array2 || (this._array2 = [
      "I want no fruit!",
      "I will have one " + randomResult(this.array1) + "."
    ])
  }
}

(您可以使用Symbol使该属性更加私密,但最好不要过于复杂的事情)

使用符号

由于评论中提到了,即使它超出了答案的范围

在大多数情况下,将属性缓存到_array2就足够了;但是酒店可以直接进入:

console.log(objectOfArrays._array2) // null

可以轻易篡改:

objectOfArrays._array2 = [1, 2];

array2中更改getter的行为。

可以使用符号使_array2更加私密。假设我们在一个模块中:

const _array2 = Symbol("array2"); // the string is just for debug

export default objectOfArrays = {
  array1: ["apple","orange","pear","mango"],
  get array2() {
    return this[_array2] || (this[_array2] = [
      "I want no fruit!",
      "I will have one " + randomResult(this.array1) + "."
    ])
  }
}

通过这种方式,在模块外部没有直接的方式来引用“私有”_array2属性,因为需要符号 - 我们不会导出它。 它也不会出现在迭代中(例如,使用Object.keys(objectOfArrays))。当然,仍有一种方法可以使用getOwnPropertySymbol来访问它,但这通常意味着比事故更加深思熟虑的代码 - 例如迭代一个对象的键。

我提到了模块,但如果我们使用块范围,这也适用:

 // create a block
 {
   // const is block scoped, therefore is not accessible outside
   const _array2 = Symbol("array2");

   // `var` is not block scoped, so it will be accessible outside
   // also `global.objectOfArrays` would be valid, where `global`
   // is a reference to the global object (there is a spec to have
   // it by default but is not implemented yet.
   var objectOfArrays = ... // same code
 }

或者在封闭中:

 (function(exports) {
   const _array2 = Symbol("array2");

   exports.objectOfArrays = ... // same code
 }(this)); // or `window` or whatever is the export object / global one.

答案 1 :(得分:0)

替代方案可以是临时变量:



var temp, objectOfArrays = {
  array1: temp = ["apple","orange","pear","mango"],
  array2: [
    "I want no fruit!",
    "I will have one " + temp + "."
  ]
}

console.log( objectOfArrays );




或单独的陈述:



var objectOfArrays = { array1: temp = ["apple","orange","pear","mango"] };

objectOfArrays.array2 = [ "I want no fruit!",
    "I will have one " + objectOfArrays.array1 + "." ];

console.log( objectOfArrays );