Изменить значения всех переменных, названных через сигнатуру функции - PullRequest
3 голосов
/ 05 ноября 2019

Допустим, у меня есть функция с 50 аргументами, и мне нужно изменить значения каждой именованной переменной, которая была создана внутри сигнатуры функции.

Вместо 50 аргументов, он пример с просто4:

// 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 может получить доступ ко всем аргументам, передаваемым в функцию, но, по-видимому, он не предлагает способ изменения значенийСами именованные переменные.

Можно ли выполнить все именованные переменные (именованные в сигнатуре функции) через функцию, которая изменяет каждую из них, прежде чем использовать эти измененные аргументы позже (используя те же имена переменных)?

Ответы [ 4 ]

4 голосов
/ 05 ноября 2019

Вы сказали, что хотите изменить значения «именованных переменных», поэтому я предполагаю, что вы имеете в виду формальные параметры (show, me и т. Д.)

Аргументыобъект может получить доступ ко всем аргументам, передаваемым в функцию, но, похоже, он не предлагает способ изменить значения самих именованных переменных.

Имеет, но только в свободном режиме,не строгий режим:

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 конструкциях.)

Live Пример:

// 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}: ?`;
}

Live Пример:

"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}: ?`;
}

Live Пример:

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

Это также работает в строгом режиме.

3 голосов
/ 05 ноября 2019

Свойства объекта arguments на самом деле являются сеттерами. Если вы переназначите свойство для аргумента, изменится и соответствующее имя переменной. Таким образом, вы можете перебрать 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 не демонстрирует это крайне не интуитивное поведение. Попробуйте вместо этого изменить свою функцию.

3 голосов
/ 05 ноября 2019

Вы имеете в виду это?

Преобразовать итерационные аргументы в массив и отобразить его

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"
1 голос
/ 05 ноября 2019

Вы можете использовать аргументы объекта javascript !! 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"
...