ES6中如何使用解构赋值定义枚举?
How to use destructuring assignment to define enumerations in ES6?
您可以使用解构赋值来定义 ES6 中的枚举,如下所示:
var [red, green, blue] = [0, 1, 2];
相反,我希望解构赋值的右侧是动态的。例如:
var MAX_ENUM_SIZE = 32;
var ENUM = new Array(MAX_ENUM_SIZE);
for (var i = 0; i < MAX_ENUM_SIZE; i++) ENUM[i] = i;
var [red, green, blue] = ENUM;
不幸的是,这似乎是一个 hack。如果将来我想要更大的枚举怎么办?因此,我正在考虑将解构赋值与迭代器一起使用,如下所示:
var [red, green, blue] = enumeration(/* I don't want to specify size */);
但是,我认为不可能将解构赋值与迭代器一起使用[需要引用]。有什么办法可以实现这个目标吗?
请注意,以下每种前瞻性方法都可能得到改进。
这些变量在问题中似乎是全局的。您可以创建一个引用应创建的变量的字符串数组,从数组的元素定义变量
// not technically destructuring, though achieves same result;
// that is, setting variables globally
for (var prop of (props = ["a", "b", "c", "d"])) {
// set identifier globally
self[prop] = props.indexOf(prop); // set a value for each `prop`
}
// delete `prop`, `props`
prop = props = void 0;
console.log(a, b, c, d);
其他方法
使用对象解构
var {
red, blue, green
} = (function(data, props) {
for (var prop of Object.keys(props)) {
data[props[prop]] = props.indexOf(props[prop]); // or some other value
};
return data
}({}, ["red", "blue", "green"]));
console.log(red, blue, green);
使用变量列表
var props = ["red", "blue", "green"]; // list of variables to be
var [red, blue, green] = props.map((v, k) => k);
console.log(red, blue, green, "window[\"red\"]:", window[props[0]]);
使用发电机
function* enumerator() {
let i = 0;
while (true) yield i++;
};
let [red,green,blue] = enumerator();
console.log(red, green, blue); // 0 1 2
let [a,b,c,d,e] = enumerator();
console.log(a,b,c,d,e); // 0 1 2 3 4
生成器非常灵活,可以非常巧妙地实现不同类型的枚举——例如,这些可爱的位掩码枚举
function* bitmask() {
let i = 0;
while (i < 32) yield 1 << i++;
throw Error("bitmask enumerator exceeds 32 bits");
}
let [R,W,X] = bitmask();
const read = p => (p & R) !== 0;
const write = p => (p & W) !== 0;
const exec = p => (p & X) !== 0;
{
let p = R | W; // read and write only
console.log("can read?", read(p)); // true
console.log("can write?", write(p)); // true
console.log("can exec?", exec(p)); // false
}
{
let p = R | X; // read and execute only
console.log("can read?", read(p)); // true
console.log("can write?", write(p)); // false
console.log("can exec?", exec(p)); // true
}
您可以使用解构赋值来定义 ES6 中的枚举,如下所示:
var [red, green, blue] = [0, 1, 2];
相反,我希望解构赋值的右侧是动态的。例如:
var MAX_ENUM_SIZE = 32;
var ENUM = new Array(MAX_ENUM_SIZE);
for (var i = 0; i < MAX_ENUM_SIZE; i++) ENUM[i] = i;
var [red, green, blue] = ENUM;
不幸的是,这似乎是一个 hack。如果将来我想要更大的枚举怎么办?因此,我正在考虑将解构赋值与迭代器一起使用,如下所示:
var [red, green, blue] = enumeration(/* I don't want to specify size */);
但是,我认为不可能将解构赋值与迭代器一起使用[需要引用]。有什么办法可以实现这个目标吗?
请注意,以下每种前瞻性方法都可能得到改进。
这些变量在问题中似乎是全局的。您可以创建一个引用应创建的变量的字符串数组,从数组的元素定义变量
// not technically destructuring, though achieves same result;
// that is, setting variables globally
for (var prop of (props = ["a", "b", "c", "d"])) {
// set identifier globally
self[prop] = props.indexOf(prop); // set a value for each `prop`
}
// delete `prop`, `props`
prop = props = void 0;
console.log(a, b, c, d);
其他方法
使用对象解构
var {
red, blue, green
} = (function(data, props) {
for (var prop of Object.keys(props)) {
data[props[prop]] = props.indexOf(props[prop]); // or some other value
};
return data
}({}, ["red", "blue", "green"]));
console.log(red, blue, green);
使用变量列表
var props = ["red", "blue", "green"]; // list of variables to be
var [red, blue, green] = props.map((v, k) => k);
console.log(red, blue, green, "window[\"red\"]:", window[props[0]]);
使用发电机
function* enumerator() {
let i = 0;
while (true) yield i++;
};
let [red,green,blue] = enumerator();
console.log(red, green, blue); // 0 1 2
let [a,b,c,d,e] = enumerator();
console.log(a,b,c,d,e); // 0 1 2 3 4
生成器非常灵活,可以非常巧妙地实现不同类型的枚举——例如,这些可爱的位掩码枚举
function* bitmask() {
let i = 0;
while (i < 32) yield 1 << i++;
throw Error("bitmask enumerator exceeds 32 bits");
}
let [R,W,X] = bitmask();
const read = p => (p & R) !== 0;
const write = p => (p & W) !== 0;
const exec = p => (p & X) !== 0;
{
let p = R | W; // read and write only
console.log("can read?", read(p)); // true
console.log("can write?", write(p)); // true
console.log("can exec?", exec(p)); // false
}
{
let p = R | X; // read and execute only
console.log("can read?", read(p)); // true
console.log("can write?", write(p)); // false
console.log("can exec?", exec(p)); // true
}