简体   繁体   English

数组中可以有Getter / Setter吗?

[英]Is it possible to have Getter/Setter in an Array?

I've just learnt about Getters/Setters for objects and decided to play with it. 我刚刚了解了对象的Getters / Setters,并决定使用它。 However, I tried to put a Getter in an array and failed to do so. 但是,我尝试将Getter放入数组中,但没有这样做。 Is it not possible or am I just doing something wrong? 这是不可能的还是我只是做错了什么?

const obj = {
  a: 1,
  get b() { return this.a + 1 } 
}

console.log(obj.b) //2

For Array 对于阵列

const arr = [
  1,
  get () { return this[0] + 1 } 
]

console.log(arr[1]) // Doesn't work

Is it not possible or am I just doing something wrong? 这是不可能的还是我只是做错了什么?

It's not possible using an array initializer (loosely, an "array literal"). 使用数组初始化器(松散地是“数组文字”)是不可能的。

You could define an accessor property after the fact, though, via Object.defineProperty : 不过,您可以通过Object.defineProperty定义一个访问器属性:

 const arr = [1]; Object.defineProperty(arr, "1", { get() { return this[0] + 1; } }); console.log(arr[1]); // 2 

You can combine that, I've left the steps above separate for clarity, but Object.defineProperty returns the object you call it on, so: 可以结合使用,为清楚起见,我将上述步骤分开进行,但是Object.defineProperty返回调用它的对象,因此:

 const arr = Object.defineProperty([1], "1", { get() { return this[0] + 1; } }); console.log(arr[1]); // 2 

I wouldn't , but you can. 我不会 ,但是可以。 :-) Why wouldn't I? :-)我为什么不呢? Because arrays expect their properties with array index names¹ to be simple data properties, not accessors, and so various array methods (like splice ) will fail if they try to set the "1" property to a different value (you could fix that by adding a setter). 因为数组希望数组索引名称¹的属性是简单的数据属性,而不是访问器,所以如果尝试将"1"属性设置为其他值,则各种数组方法(例如splice )都会失败(您可以通过添加setter)。 In general, though, I'd leave array entry properties alone. 不过,总的来说,我会不理会数组条目的属性。

That said, if the property has both a getter and a setter, I can't immediately think of a problem with it. 就是说,如果该属性同时具有getter和setter,那么我将无法立即想到它的问题。 Here's the above with a setter, just for completeness: 上面是带有二传手的内容,仅用于完整性方面:

 const arr = Object.defineProperty([1], "1", { get() { return this[0] + 1; }, set(value) { this[0] = value - 1; } }); console.log(arr); // [1, 2] arr[1] = 42; console.log(arr); // [41, 42] arr[0] = 27; console.log(arr); // [27, 28] 
 .as-console-wrapper { max-height: 100% !important; } 


¹ "array index names" - Here's what the spec says about property names that are array indexes: ¹“数组索引名称”-这是规范对数组索引的属性名称的说明:

An integer index is a String-valued property key that is a canonical numeric String (see 7.1.16) and whose numeric value is either +0 or a positive integer ≤ 2 53 - 1. An array index is an integer index whose numeric value i is in the range +0 ≤ i < 2 32 - 1. 整数指数是一个字符串值属性密钥是一个规范的数字串(见7.1.16),并且其数字值是0或正整数2≤53 - 1 数组索引整数指数 ,其数值i是范围为0≤I <2 32 - 1。

Instead of using a setter/getter, you could use a Proxy instead and evaluate the accessor and return different values. 除了使用setter / getter,还可以使用Proxy来评估访问器并返回不同的值。

 var handler = { get: function(obj, prop) { return prop in obj ? obj[prop] : obj[0] + 1; } }; var p = new Proxy([1], handler); console.log(p[1]); p.push(10) console.log(p[1]); console.log(p[2]); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM