元组中的 JavaScript 变量赋值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4512405/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript variable assignments from tuples
提问by Karl
In other languages like Python 2 and Python 3, you can define and assign values to a tuple variable, and retrieve their values like this:
在 Python 2 和 Python 3 等其他语言中,您可以定义元组变量并为其赋值,并像这样检索它们的值:
tuple = ("Bob", 24)
name, age = tuple
print(name) #name evaluates to Bob
print(age) #age evaluates to 24
Is there anything similar in JavaScript? Or do I just have to do it the ugly way with an array:
JavaScript 中有类似的东西吗?或者我是否只需要使用数组以丑陋的方式来做:
tuple = ["Bob", 24]
name = tuple[0] //name Evaluates to Bob
age = tuple[1] //age Evaluates to 24
Is there a better way to simulate Python tuples in JavaScript 5?
有没有更好的方法来模拟 JavaScript 5 中的 Python 元组?
Update:See the answer regarding ES6, which should be favored over CoffeeScript for new projects.
更新:请参阅有关 ES6 的答案,对于新项目,它应该比 CoffeeScript 更受青睐。
回答by pc1oad1etter
Javascript 1.7 added destructured assignmentwhich allows you to do essentially what you are after.
Javascript 1.7 添加了解构赋值,使您基本上可以做您想做的事情。
function getTuple(){
return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true
回答by Gabi Purcaru
You have to do it the ugly way. If you reallywant something like this, you can check out CoffeeScript, which has that and a whole lot of other features that make it look more like python (sorry for making it sound like an advertisement, but I really like it.)
你必须以丑陋的方式去做。如果你真的想要这样的东西,你可以看看CoffeeScript,它有它和很多其他功能,使它看起来更像 python (抱歉让它听起来像一个广告,但我真的很喜欢它。)
回答by monika mevenkamp
You can do something similar:
你可以做类似的事情:
var tuple = Object.freeze({ name:'Bob', age:14 })
and then refer to name and age as attributes
然后将姓名和年龄称为属性
tuple.name
tuple.age
回答by Adrian
This "tuple" feature it is called destructuring in EcmaScript2015 and is soon to be supported by up to date browsers. For the time being, only Firefox and Chrome support it.
这个“元组”特性在 EcmaScript2015 中被称为解构,很快就会被最新的浏览器支持。暂时只有 Firefox 和 Chrome 支持。
But hey, you can use a transpiler.
但是,嘿,您可以使用转译器。
The code would look as nice as python:
代码看起来和 python 一样好:
let tuple = ["Bob", 24]
let [name, age] = tuple
console.log(name)
console.log(age)
回答by Matthew James Davis
A frozen array behaves identically to a python tuple:
冻结数组的行为与 Python 元组相同:
const tuple = Object.freeze(["Bob", 24]);
let [name, age]; = tuple
console.debug(name); // "Bob"
console.debug(age); // 24
Be fancy and define a class
花哨并定义一个类
class Tuple extends Array {
constructor(...items) {
super(...items);
Object.freeze(this);
}
}
let tuple = new Tuple("Jim", 35);
let [name, age] = tuple;
console.debug(name); // Jim
console.debug(age); // 35
tuple = ["Bob", 24]; // no effect
console.debug(name); // Jim
console.debug(age); // 25
Works today in all the latest browsers.
今天适用于所有最新的浏览器。
回答by Evan Plaice
Tuples aren't supported in JavaScript
JavaScript 不支持元组
If you're looking for an immutable list, Object.freeze() can be used to make an array immutable.
如果您正在寻找不可变列表,则 Object.freeze() 可用于使数组不可变。
The Object.freeze() method freezes an object: that is, prevents new properties from being added to it; prevents existing properties from being removed; and prevents existing properties, or their enumerability, configurability, or writability, from being changed. In essence the object is made effectively immutable. The method returns the object being frozen.
Object.freeze() 方法冻结一个对象:也就是说,阻止向它添加新属性;防止删除现有属性;并防止现有属性或其可枚举性、可配置性或可写性被更改。本质上,对象实际上是不可变的。该方法返回被冻结的对象。
Source: Mozilla Developer Network - Object.freeze()
来源:Mozilla 开发者网络 - Object.freeze()
Assign an array as usual but lock it using 'Object.freeze()
像往常一样分配一个数组,但使用 'Object.freeze() 锁定它
> tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]
Use the values as you would a regular array (python multi-assignment is not supported)
像使用常规数组一样使用这些值(不支持 python 多赋值)
> name = tuple[0]
'Bob'
> age = tuple[1]
24
Attempt to assign a new value
尝试分配一个新值
> tuple[0] = 'Steve'
'Steve'
But the value is not changed
但值没有改变
> console.log(tuple)
[ 'Bob', 24 ]
回答by meder omuraliev
Unfortunately you can't use that tuple assignment syntax in (ECMA|Java)Script.
不幸的是,您不能在 (ECMA|Java)Script 中使用该元组赋值语法。
EDIT: Someone linked to Mozilla/JS 1.7 - this wouldn't work cross-browser but if that is not required then there's your answer.
编辑:有人链接到 Mozilla/JS 1.7 - 这不会跨浏览器工作,但如果不需要,那么你的答案。
回答by ninjagecko
This is not intended to be actually used in real life, just an interesting exercise. See Why is using the JavaScript eval function a bad idea?for details.
这并不打算在现实生活中实际使用,只是一个有趣的练习。请参阅为什么使用 JavaScript eval 函数是个坏主意?详情。
This is the closest you can get without resorting to vendor-specific extensions:
这是您无需求助于特定于供应商的扩展即可获得的最接近的结果:
myArray = [1,2,3];
eval(set('a,b,c = myArray'));
Helper function:
辅助功能:
function set(code) {
var vars=code.split('=')[0].trim().split(',');
var array=code.split('=')[1].trim();
return 'var '+vars.map(function(x,i){return x+'='+array+'['+i+']'}).join(',');
}
Proof that it works in arbitrary scope:
证明它可以在任意范围内工作:
(function(){
myArray = [4,5,6];
eval(set('x,y,z = myArray'));
console.log(y); // prints 5
})()
eval
is not supported in Safari.
eval
Safari 不支持。
回答by Zach Dahl
As an update to The Minister's answer, you can now do this with es2015:
作为部长回答的更新,您现在可以使用 es2015 执行此操作:
function Tuple(...args) {
args.forEach((val, idx) =>
Object.defineProperty(this, "item"+idx, { get: () => val })
)
}
var t = new Tuple("a", 123)
console.log(t.item0) // "a"
t.item0 = "b"
console.log(t.item0) // "a"
回答by Zach Dahl
You can have a tuple type in Javascript as well. Just define it with higher order functions (the academic term is Church encoding):
您也可以在 Javascript 中使用元组类型。只需用高阶函数定义它(学术术语是 Church encoding):
const Tuple = (...args) => {
const Tuple = f => f(...args);
return Object.freeze(Object.assign(Tuple, args));
};
const get1 = tx => tx((x, y) => x);
const get2 = tx => tx((x, y) => y);
const bimap = f => g => tx => tx((x, y) => Tuple(f(x), g(y)));
const toArray = tx => tx((...args) => args);
// aux functions
const inc = x => x + 1;
const toUpperCase = x => x.toUpperCase();
// mock data
const pair = Tuple(1, "a");
// application
console.assert(get1(pair) === 1);
console.assert(get2(pair) === "a");
const {0:x, 1:y} = pair;
console.log(x, y); // 1 a
console.log(toArray(bimap(inc) (toUpperCase) (pair))); // [2, "A"]
const map = new Map([Tuple(1, "a"), Tuple(2, "b")]);
console.log(map.get(1), map.get(2)); // a b
Please note that Tuple
isn't used as a normal constructor. The solution doesn't rely on the prototype system at all, but solely on higher order functions.
请注意,Tuple
它不用作普通构造函数。该解决方案根本不依赖于原型系统,而仅依赖于高阶函数。
What are the advantages of tuples over Array
s used like tuples? Church encoded tuples are immutable by design and thus prevent side effects caused by mutations. This helps to build more robust applications. Additionally, it is easier to reason about code that distinguishes between Array
s as a collection type (e.g. [a]
) and tuples as related data of various types (e.g. (a, b)
).
元组与Array
像元组一样使用的 s有什么优点?Church 编码的元组在设计上是不可变的,因此可以防止由突变引起的副作用。这有助于构建更健壮的应用程序。此外,更容易推断将Array
s 作为集合类型(例如[a]
)和元组作为各种类型的相关数据(例如(a, b)
)的代码。