在Python 2和Python 3等其他语言中,您可以将值定义和分配给元组变量,并像这样检索其值:

tuple = ("Bob", 24)
name, age = tuple
print(name)           #name evaluates to Bob
print(age)            #age evaluates to 24

JavaScript中有类似的东西吗?还是我只需要以一个丑陋的方式来做:

tuple = ["Bob", 24]
name = tuple[0]       //name Evaluates to Bob
age = tuple[1]        //age Evaluates to 24

有没有更好的方法来模拟JavaScript 5中的Python元组?

有帮助吗?

解决方案

您必须以丑陋的方式做。如果你 真的 想要这样的东西,您可以检查一下 咖啡本, ,它具有该功能和许多其他功能,使其看起来更像是Python(很抱歉使其听起来像是广告,但我真的很喜欢。)

其他提示

JavaScript 1.7添加 破坏的任务 这使您可以从本质上完成自己的目标。

function getTuple(){
   return ["Bob", 24];
}
var [a, b] = getTuple();
// a === "bob" , b === 24 are both true

您可以做类似的事情:

var tuple = Object.freeze({ name:'Bob', age:14 })

然后将名称和年龄称为属性

tuple.name 
tuple.age 

此“元组”功能在Ecmascript2015中被称为破坏,很快将得到最新的浏览器的支持。暂且, 只有Firefox和Chrome支持它.

但是,嘿,您可以使用 转板器.

该代码看起来像Python一样好:

let tuple = ["Bob", 24]
let [name, age] = tuple

console.log(name)
console.log(age)

冷冻阵列的行为与Python元组相同:

const tuple = Object.freeze(["Bob", 24]);
let [name, age]; = tuple
console.debug(name); // "Bob"
console.debug(age); // 24

幻想并定义课堂

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

今天在所有最新浏览器中工作。

不幸的是,您无法在(ECMA | Java)脚本中使用该元组分配语法。

编辑:与Mozilla/JS 1.7链接的人 - 这是不起作用的跨浏览器,但是如果不需要,则有您的答案。

JavaScript不支持元组

如果您正在寻找不变的列表,则可以使用object.freeze()使数组不变。

object.freeze()方法冻结了一个对象:即防止新属性添加到其上;防止现有属性被删除;并防止现有属性,或其枚举性,可配置性或可写入性。从本质上讲,物体有效地不变。该方法返回对象被冷冻。

资源: Mozilla开发人员网络-Oboce.freeze()

像往常

> tuple = Object.freeze(['Bob', 24]);
[ 'Bob', 24 ]

按照常规数组使用这些值(不支持Python多分配)

> name = tuple[0]
'Bob'
> age = tuple[1]
24

尝试分配新值

> tuple[0] = 'Steve'
'Steve'

但是价值没有改变

> console.log(tuple)
[ 'Bob', 24 ]

这并不是要在现实生活中实际使用的,而只是一个有趣的练习。看 为什么使用JavaScript eval函数是个坏主意? 有关详细信息。

这是您可以获得的最接近的,而无需诉诸于供应商特定的扩展:

myArray = [1,2,3];
eval(set('a,b,c = myArray'));

助手功能:

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(',');
}

证明它在任意范围中起作用:

(function(){
    myArray = [4,5,6];
    eval(set('x,y,z = myArray'));
    console.log(y);  // prints 5
})()

eval 在野生动物园中不支持。

作为对部长答案的更新,您现在可以使用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

您也可以在JavaScript中使用元组类型。只需使用高阶功能定义它(学术术语是教会编码):

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

请注意 Tuple 不用用作普通构造函数。该解决方案完全不依赖原型系统,而仅仅取决于高阶功能。

分组的优势是什么 ArrayS像元组一样使用吗?教堂编码的元素是通过设计不变的,因此可以防止突变引起的副作用。这有助于构建更强大的应用程序。此外,更容易理解区分的代码 ArrayS作为收集类型(例如 [a])和元组作为各种类型的相关数据(例如 (a, b)).

这是一个简单的JavaScript元组实现:

var Tuple = (function () {
   function Tuple(Item1, Item2) {
      var item1 = Item1;
      var item2 = Item2;
      Object.defineProperty(this, "Item1", {
          get: function() { return item1  }
      });
      Object.defineProperty(this, "Item2", {
          get: function() { return item2  }
      });
   }
   return Tuple;
})();

var tuple = new Tuple("Bob", 25); // Instantiation of a new Tuple
var name = tuple.Item1; // Assignment. name will be "Bob"
tuple.Item1 = "Kirk"; // Will not set it. It's immutable.

但是,这是一个2核心,您可以修改我的示例以支持3,4,5,6等。

[a, b, c] = [2, 'momo', 7]  // b === 'momo', c ===7 ...
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top