我以前做过类似的事情,但我无法让它发挥作用。
我运行它并获得“无法读取属性'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));
答案 0 :(得分:2)
对象尚未定义,您不能在对象声明中使用this
。
要清楚,就像那样:
const obj = {
a: 1,
b: this.a,
c: obj.a
}
无效,b
和c
无法访问当前声明的对象。
但是,如果您延迟访问权限,那么它将起作用:
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 );