JavaScript,js培训班
您的位置: 主页 > web前端文章 > javascript >

JavaScript中的左变量函数【访问量:115】

一个可变参数函数被设计成接受可变数量的参数。1在JavaScript中,您可以通过收集参数来创建可变参数功能。例如:

const abccc = (a, b, …c) => {
console.log(a);
console.log(b);
console.log(c);
};
abccc(1, 2, 3, 4, 5)
1
2
[3,4,5]

在编写某些类型的解构算法时,这会很有用。例如,我们可能想要一个可以创建某种团队记录的函数。它接受教练,队长和任意数量的球员。在ECMAScript 2015中轻松:

function team(coach, captain, …players) {
console.log(——${captain} (captain)——);
for (let player of players) {
console.log(player);
}
console.log(——squad coached by ${coach}——);
}
team('Luis Enrique', 'Xavi Hernández', 'Marc-André ter Stegen', 'Martín Montoya', 'Gerard Piqué')
//=>
Xavi Hernández (captain)
Marc-André ter Stegen
Martín Montoya
Gerard Piqué
squad coached by Luis Enrique

但我们不能相反:

function team2(…players, captain, coach) {
console.log(——${captain} (captain)——);
for (let player of players) {
console.log(player);
}
console.log(——squad coached by ${coach}——);
}
//=> Unexpected token

ECMAScript 2015只允许从参数列表的末尾收集参数。不是开始。该怎么办?

历史课

在“Ye Olde Days”中,2 JavaScript无法收集参数,我们不得不使用argumentsand 来做后空翻。slice,或者我们自己写了一个variadic装饰器,它可以将参数收集到最后声明的参数中。这是它的所有ECMAScript-5荣耀:

var __slice = Array.prototype.slice;
function rightVariadic (fn) {
if (fn.length < 1) return fn;
return function () {
var ordinaryArgs = (1 <= arguments.length ?
__slice.call(arguments, 0, fn.length - 1) : []),
restOfTheArgsList = __slice.call(arguments, fn.length - 1),
args = (fn.length <= arguments.length ?
ordinaryArgs.concat([restOfTheArgsList]) : []);
return fn.apply(this, args);
}
};
var firstAndButFirst = rightVariadic(function test (first, butFirst) {
return [first, butFirst]
});
firstAndButFirst('why', 'hello', 'there', 'little', 'droid')
//=> ["why",["hello","there","little","droid"]]

我们不再需要rightVariadic,因为不是:

var firstAndButFirst = rightVariadic(
function test (first, butFirst) {
return [first, butFirst]
});

我们现在简单地写:

const firstAndButFirst = (first, …butFirst) =>
[first, butFirst];

这是一个右变量函数,这意味着它有一个或多个固定的参数,其余的被收集到最右边的参数中。

克服限制

有进展很高兴。但如上所述,我们不能写:

const butLastAndLast = (…butLast, last) =>
[butLast, last];

这是一个左变量函数。所有left-variadic函数都有一个或多个固定参数,其余参数集中在最左边的参数中。JavaScript不会这样做。但是,如果我们想要编写左变量函数,我们可以让自己成为一个leftVariadic装饰器,将具有一个或多个参数的函数变成左变量函数吗?

我们确实可以通过使用这些技术rightVariadic.请注意,我们可以利用现代JavaScript来简化代码:

const leftVariadic = (fn) => {
if (fn.length < 1) {
return fn;
}
else {
return function (…args) {
const gathered = args.slice(0, args.length - fn.length + 1),
spread   = args.slice(args.length - fn.length + 1);
return fn.apply(
this, [gathered].concat(spread)
);
}
}
};
const butLastAndLast = leftVariadic((butLast, last) =>
[butLast, last]);
butLastAndLast('why', 'hello', 'there', 'little', 'droid')
//=> [["why","hello","there","little"],"droid"]

我们的leftVariadic函数是一个装饰器,它将任何函数变成一个从左边收集参数的函数,而不是从右边收集参数。

左变异解构

为函数收集参数是JavaScript可以解构数组的方法之一。另一种方式是分配变量时,如下所示:

const [first, …butFirst] = ['why', 'hello', 'there', 'little', 'droid'];
first
//=> 'why'
butFirst
//=> ["hello","there","little","droid"]

与参数一样,解构数组时,我们无法从左边收集值:

const […butLast, last] = ['why', 'hello', 'there', 'little', 'droid'];
//=> Unexpected token

我们可以用leftVariadic艰难的方式:

const [butLast, last] = leftVariadic((butLast, last) =>
[butLast, last])(…['why', 'hello', 'there', 'little', 'droid']);
butLast
//=> ['why', 'hello', 'there', 'little']
last
//=> 'droid'

但是,我们可以使用相同的原则编写我们自己的左收集函数实用程序,而不用单调乏味:

const leftGather = (outputArrayLength) => {
return function (inputArray) {
const gathered = inputArray.slice(0, inputArray.length - outputArrayLength + 1),
spread = inputArray.slice(inputArray.length - outputArrayLength + 1);
return [gathered].concat(spread);
}
};
const [butLast, last] = leftGather(2)(['why', 'hello', 'there', 'little', 'droid']);
butLast
//=> ['why', 'hello', 'there', 'little']
last
//=> 'droid'

使用时leftGather,我们必须提供我们希望用作结果的数组的长度,并且从左边leftVariadic收集多余的参数,就像收集函数的多余参数一样。


2018-04-03
匿名评论