可以为 JavaScript 数组定义 Getter 和 Setter。但是您不能同时拥有访问器和值。请参阅 Mozilla文档:
不可能同时将 getter 绑定到一个属性并让该属性实际持有一个值
因此,如果您为数组定义访问器,则需要为实际值设置第二个数组。下面的例子说明了它。
//
// Poor man's prepare for querySelector.
//
// Example:
// var query = prepare ('#modeler table[data-id=?] tr[data-id=?]');
// query[0] = entity;
// query[1] = attribute;
// var src = document.querySelector(query);
//
var prepare;
{
let r = /^([^?]+)\?(.+)$/; // Regular expression to split the query
prepare = function (query, base)
{
if (!base) base = document;
var q = []; // List of query fragments
var qi = 0; // Query fragment index
var v = []; // List of values
var vi = 0; // Value index
var a = []; // Array containing setters and getters
var m; // Regular expression match
while (query) {
m = r.exec (query);
if (m && m[2]) {
q[qi++] = m[1];
query = m[2];
(function (qi, vi) {
Object.defineProperty (a, vi, {
get: function() { return v[vi]; },
set: function(val) { v[vi] = val; q[qi] = JSON.stringify(val); }});
})(qi++, vi++);
} else {
q[qi++] = query;
query = null;
}
}
a.toString = function () { return q.join(''); }
return a;
}
}
该代码使用三个数组:
- 一个用于实际值,
- 一个用于 JSON 编码的值
- 一个用于访问器。
带有访问器的数组返回给调用者。当set
通过为数组元素分配一个值来调用 a 时,包含普通值和编码值的数组将被更新。当get
被调用时,它只返回普通值。并toString
返回包含编码值的整个查询。
但正如其他人已经指出的那样:只有当数组的大小恒定时,这才有意义。您可以修改数组的现有元素,但不能添加其他元素。