JavaScript变量分配分配
-
12-10-2019 - |
题
在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"
您也可以在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
不用用作普通构造函数。该解决方案完全不依赖原型系统,而仅仅取决于高阶功能。
分组的优势是什么 Array
S像元组一样使用吗?教堂编码的元素是通过设计不变的,因此可以防止突变引起的副作用。这有助于构建更强大的应用程序。此外,更容易理解区分的代码 Array
S作为收集类型(例如 [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 ...