【问题标题】:Change Values of All Variables Named via Function Signature更改通过函数签名命名的所有变量的值
【发布时间】:2020-03-01 13:56:05
【问题描述】:

假设我有一个有 50 个参数的函数,我需要修改在函数签名中创建的每个命名变量的值。

他只有 4 个参数,而不是 50 个参数:

// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(show, me, the, bunny)
{
	// I want to trim each argument, without having to do this:
	show = show.trim();
	me = me.trim();
	the = the.trim();
	bunny = bunny.trim();
	// The above lines, within this function,
	// are the ones I want to replace with a loop (if possible)

	return `${show} ${me} ${the} ${bunny}: ????`; 
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny: ????"

arguments 对象可以访问传递给函数的所有参数,但它似乎没有提供更改命名变量本身值的方法。

是否可以通过一个修改每个变量的函数来运行所有命名变量(在函数签名中命名),然后再使用这些修改后的参数(使用相同的变量名)?

【问题讨论】:

  • “假设我有一个有 50 个参数的函数......” 你好!
  • 我不明白你所说的named-variables 是什么意思,你能显示一个unnamed-variable 吗?
  • @LonnieBest:我明白了。通常此类函数有一个签名sqlExecute(statement, args),如果使用位置占位符,args 是一个数组,如果使用命名占位符,则是一个对象。
  • @LonnieBest - 是的。你可以通过使用解构来解决这个问题。例如,假设您接受一个对象:for (const [name, value] of Object.entries(args)) { args[name] = value.trim(); } 后跟 const {show, me, the, bunny} = args;。它的优点是您不必担心订单。
  • @LonnieBest:是的,但谁说你必须使用模板?使用您自己的占位符传递一个普通字符串,例如 WHERE {whatever} > 0 并即时替换它们。模板在这里是一个错误的工具。

标签: javascript ecmascript-next


【解决方案1】:

您说过要修改“命名变量”的值,所以我假设您的意思是形式参数(showme 等)

arguments 对象可以访问传递给函数的所有参数,但它似乎没有提供一种方法来更改命名变量本身的值。

确实如此,但仅限于松散模式,而不是严格模式:

function showMeTheBunny(show, me, the, bunny)
{
    for (let n = 0; n < arguments.length; ++n)
    {
        arguments[n] = arguments[n].trim();
    }
    return `${show} ${me} ${the} ${bunny}: ?`;
}

其中,arguments[0] = arguments[0].trim() 更新show 形式参数的值,arguments[1] = arguments[1].trim() 更新me 等。但仅限于松散模式。在严格模式下,只会更新arguments[x],不会更新形参;返回它的链接被删除。 (值得注意的是,严格模式是模块和class 构造中的默认设置。)

现场示例:

// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(show, me, the, bunny)
{
    for (let n = 0; n < arguments.length; ++n)
    {
        arguments[n] = arguments[n].trim();
    }
	return `${show} ${me} ${the} ${bunny}: ?`;
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny"

还有其他方法,但它们不会修改形参的值。例如,您可以使用 rest 参数:

function showMeTheBunny(...rest)
{
    rest = rest.map(entry => entry.trim());
    const [show, me, the, bunny] = rest;
    return `${show} ${me} ${the} ${bunny}: ?`;
}

现场示例:

"use strict";
// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(...rest)
{
    rest = rest.map(entry => entry.trim());
    const [show, me, the, bunny] = rest;
	return `${show} ${me} ${the} ${bunny}: ?`;
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny"

这在严格模式下有效。

另一种选择是接受具有参数属性的对象,然后(再次)使用解构来获取单个变量:

function showMeTheBunny(args)
{
    for (const [name, value] of Object.entries(args)) {
        args[name] = value.trim();
    }
    const {show, me, the, bunny} = args;
    return `${show} ${me} ${the} ${bunny}: ?`;
}

现场示例:

"use strict";
// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(args)
{
    for (const [name, value] of Object.entries(args)) {
        args[name] = value.trim();
    }
    const {show, me, the, bunny} = args;
	return `${show} ${me} ${the} ${bunny}: ?`;
}
console.log(showMeTheBunny({show, me, the, bunny})); // output: "show me the bunny"

这也适用于严格模式。

【讨论】:

  • 因此,如果我在 ES6 模块中执行此操作,它将自动处于严格模式。因此在这种情况下它不会起作用吗?
  • @LonnieBest - 没错。在这种情况下,您需要执行类似于我的第二个或第三个选项的操作。
  • @mplungjan - 感谢您的编辑!我没有看到 OP 在问题中解决了这个问题。
【解决方案2】:

arguments 对象的属性实际上是 setter。如果您重新分配参数的属性,相应的变量名称也会更改。因此,您可以遍历 arguments 并重新分配它们:

// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(show, me, the, bunny)
{
  [...arguments].forEach((arg, i) => {
    arguments[i] = arg.trim();
  });
	return `${show} ${me} ${the} bunny`; 
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny"

但这真的很奇怪。 Javascript 中几乎没有其他任何东西表现出这种极其不直观的行为。考虑改变你的功能。

【讨论】:

  • 值得注意的是arguments 在严格模式下不会这样表现。返回形式参数的链接已删除。
  • @T.J.Crowder 我从未使用过严格的。 My answer 确实可以使用它。你有什么疑虑?
  • 啊,不允许重写参数
  • @mplungjan - 对。 arguments[0] = x 在严格模式下不会更改 show。您的答案有效,因为您不使用形式参数。
【解决方案3】:

你是说这个吗?

将迭代参数转换为数组并映射

Array.from(arguments)[...arguments] 将在这里工作

这实际上并没有像 TJ 所指出的那样修改实际的参数数组

// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(show, me, the, bunny) {
  return Array.from(arguments).map(el => el.trim()).join(" ")+": ?";
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny"

【讨论】:

  • OP 说他们想改变形参的值。这不会那样做。
  • @T.J.Crowder 他最终说过(在我发布后,由你提示):) 我们确定他真的是那个意思吗?我的意思是,有什么意义。
  • 不,它在the first version of the question。从最后两段可以清楚地看出“命名变量”是什么意思。
  • @T.J.Crowder 对。我仍然不明白为什么这样做会有用
  • 这仍然是一个有趣的答案。谢谢。
【解决方案4】:

你可以使用javascript的arguments对象!! https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments

// Each of these strings are padded with intentional and unnecessary whitespace:
let show = "  show ";
let me = " me  ";
let the = " the ";
let bunny = "  bunny   ";

function showMeTheBunny(show, me, the, bunny)
{
    var retString = "";
	for (var i = 0; i < arguments.length; i++) {
       retString += arguments[i].trim() + " ";
    }

	return retString.trim(); 
}
console.log(showMeTheBunny(show, me, the, bunny)); // output: "show me the bunny"

【讨论】:

  • 不优雅。你的兔子会有一个尾随空格
  • @mplungjan 不会的,看看return语句:)
  • 现在不会了。与连接相比仍然不优雅
猜你喜欢
  • 1970-01-01
  • 2023-01-30
  • 2018-03-07
  • 2018-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多