元组中的 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 12:44:13  来源:igfitidea点击:

JavaScript variable assignments from tuples

javascripttuplesdestructuring

提问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
})()

evalis not supported in Safari.

evalSafari 不支持。

回答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"

https://jsbin.com/fubaluwimo/edit?js,console

https://jsbin.com/fubaluwimo/edit?js,console

回答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 Tupleisn'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 Arrays 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 Arrays as a collection type (e.g. [a]) and tuples as related data of various types (e.g. (a, b)).

元组与Array像元组一样使用的 s有什么优点?Church 编码的元组在设计上是不可变的,因此可以防止由突变引起的副作用。这有助于构建更健壮的应用程序。此外,更容易推断将Arrays 作为集合类型(例如[a])和元组作为各种类型的相关数据(例如(a, b))的代码。