数组中可以有Getter / Setter吗?

时间:2018-12-30 10:32:01

标签: javascript arrays

我刚刚了解了对象的Getters / Setters,并决定使用它。但是,我尝试将Getter放入数组中,但没有这样做。是不可能的,还是我只是做错了什么?

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

console.log(obj.b) //2

对于阵列

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

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

2 个答案:

答案 0 :(得分:4)

  

是不可能还是我做错了什么?

使用数组初始化程序(松散地是“数组文字”)是不可能的。

但是,您可以在事实之后通过Object.defineProperty定义访问器属性:

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

console.log(arr[1]); // 2

您可以结合使用,为清楚起见,我将上面的步骤分开,但是Object.defineProperty返回了您调用它的对象,所以:

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

console.log(arr[1]); // 2

我不会,但是可以。 :-)我为什么不呢?因为数组希望数组索引名称¹的属性是简单的数据属性,而不是访问器,所以如果尝试将splice属性设置为其他值,各种数组方法(例如"1")将会失败(您可以通过添加设置器来解决此问题)。不过,总的来说,我会不理会数组条目的属性。

也就是说,如果该属性同时具有getter和setter,那么我就不能立即想到它的问题。上面是带有二传手的内容,只是为了完整性:

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;
}


¹“数组索引名”-这是关于the spec says关于数组索引的属性名的信息:

  

整数索引是一个字符串值的属性键,它是规范的数字字符串(请参见7.1.16),其数值为+0或正整数≤2 53 -1. 数组索引是一个整数索引,其数值 i 在+0≤i <2 < sup> 32 -1。

答案 1 :(得分:2)

您可以使用Proxy而不是使用setter / getter来评估访问器并返回不同的值。

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]);