#parameters #javascript
#параметры #javascript
Вопрос:
я создаю достаточно большое JS-приложение, и я хотел бы узнать ваше мнение о некоторой логике. я хотел знать, считается ли плохой практикой передавать параметр через строку функций, например
function start(){
var param1 = 'me';
secondFunction(param1);
}
function secondFunction(param1){
//i dont want to user the param in this function
$.ajax('url',data,success(){
third(param1);
});
}
function third(param1){
alert(param1);
}
я предполагаю, что альтернативой является использование глобальных переменных, как показано ниже. Но в моем случае у меня уже есть масса глобальных переменных, и, на мой взгляд, некоторые вещи недостаточно важны для глобальной работы приложения.
var param1;
function start(){
param1 = 'me';
secondFunction();
}
function secondFunction(){
//i dont want to user the param in this function
$.ajax('url',data,success(){
third();
});
}
function third(){
alert(param1);
}
Итак, вы бы сказали, что передача параметров через более чем одну функцию в порядке, или я должен делать это другим способом?
Спасибо
Комментарии:
1. Вместо тонны глобальных переменных вы можете создать пространство имен (по сути, объект) и присвоить ему свои переменные. Таким образом, у вас есть только одна глобальная переменная, и вы все равно можете получить доступ ко всему.
Ответ №1:
На самом деле, это хорошая практика, потому что она позволяет избежать какого-либо глобального состояния (т. Е. в идеале поведение функции должно зависеть только от ее параметров).
Если у вас есть много параметров, которые нужно передать таким образом, я бы объединил их в отдельный объект (объект ‘environment’), но в остальном все в порядке.
Выполнение этого способа дает вам большую гибкость — если вы хотите, чтобы функция работала с разными данными один раз, вы бы просто передали разные значения, а не меняли глобальное состояние, что может повлиять и на все остальное (отсутствие таких глобальных побочных эффектов очень упрощает распараллеливание функций, хотя это может быть не так важно для JavaScript).
Комментарии:
1. Примером для «объекта enviroment», предложенного Алексом, может быть:
secondFunction({param1:'me', param2:'you'});
а затем в secondFunctionthird(parameterObject);
.2. На самом деле распараллеливание здесь очень важный момент. Поскольку он выполняет однократный вызов ajax в
secondFunction
браузере, он вернется к циклу событий после вызоваsecondFunction
и, следовательно, до вызова функцииthird
. По этой причине потенциальный второй вызовstart
может произойти до того,third
как вызывается асинхронный обратный вызов ajax для первого вызоваstart
.3. Я согласен. Передача параметров — очень хорошая практика. Он поддерживает повторное использование, а также помогает поддерживать чистое глобальное пространство имен. Количество времени, которое требуется для передачи параметров в сравнении с доступом к глобальному объекту, ничтожно мало (по крайней мере, для быстрых временных испытаний, которые я проводил).
Ответ №2:
Гораздо лучше передавать параметры через несколько функций, чем использовать глобальные.
Например, это позволяет запускать процесс несколько раз, не нарушая глобальное состояние.
Ответ №3:
Короче говоря, я бы придерживался передачи переменных, чтобы избежать конфликтов области видимости и поддерживать правильную работу одновременных вызовов. Однако я бы изменил формат, в котором вы их передаете:
Поскольку JavaScript настолько гибок с объектами, мне нравится иметь один всеобъемлющий параметр для функций, которым может потребоваться несколько параметров. Это улучшает видимость при вызове функции, упрощает расширение функции для поддержки дополнительных параметров и необязательных параметров, а в вашем случае упрощает передачу параметров дополнительным функциям в цепочке. Единственным недостатком являются более длинные вызовы функций, но я считаю, что преимущества того стоят. Например:
/**
* ..
*
* params.test1 Test 1 does blah
* params.test2 Test 2 does blah 2
* params.test3 Test 3 does blah 3
* params.test4 Test 4 does blah 4
*/
function test(params){
//Initialize Parameters
var test1 = params.test1;
var test2 = params.test2;
//function code
..
test2(params);
..
}
/**
* ..
*
* params.test1 Test 3 does blah 3
* params.test2 Test 4 does blah 4
*/
function test2(params){
var test3 = params.test3;
var test4 = params.test4;
//function code using test3 and test4
..
}
//Call the test function
test({test1: 'foo1', test2: 'foo2', test3: 'foo3', test4: 'foo4'});
Ответ №4:
Я не вижу ничего плохого ни в одном из стилей. Метод предпочтения здесь, на самом деле.
Единственным недостатком глобальных переменных является то, что они остаются в памяти на протяжении всего срока службы приложения.
Комментарии:
1. Это неверно. Вызов
start()
несколько раз до завершения асинхронного вызова ajax переопределитparam1
установленный в предыдущих вызовахstart()
. Предполагая, что значение, присвоенноеparam1
, на самом деле не является постоянным, это испортит состояние предыдущих вызововstart()
.2. В этом контексте его вопроса param1 всегда будет иметь одно и то же значение. Хотя спасибо за ваше мнение.
3. Скорее всего, он не присваивает постоянное значение параметру1 в своем реальном коде. Если это так, использование глобальной переменной нарушит его программу. По этой причине (и по ряду других) обычно считается плохой практикой использование глобальных переменных, и их использования следует избегать. Таким образом, это не просто вопрос предпочтения или стиля, а выбор между кодом, который потенциально может нарушить работу вашего приложения, и кодом, который не нарушит работу вашего приложения. Не используйте глобальные переменные, если этому есть реальная альтернатива.
Ответ №5:
в javascript есть особый способ определения переменных области видимости, в первом примере вы определяете param1 в start , поэтому все созданные потоки и функции, которые были вызваны в контексте функций start, имеют переменную param1 «inherit» для вызова каким-либо образом. таким образом, все операторы, используемые вне start, не имеют определенной переменной param1. Итак, вам нужно использовать эту область видимости переменной, только когда вам нужно использовать переменную в потоке или серии вызываемых функций.
во втором примере используется глобальная переменная scope, это означает, что переменная используется с глобальным значением независимо от того, в каком потоке вы ее вызвали, это применимо, только если вы не определяете снова param1 внутри другого контекста.
итак, зависит от того, что вы пытаетесь сделать, в приведенном выше примере наиболее эффективным является второй
Ответ №6:
Это несколько сложный вопрос для ответов, поскольку все зависит от решаемой задачи.
Причина передачи параметра каждой функции заключается в том, что вы можете захотеть повторно использовать функции для других целей или в другом порядке. В такой ситуации вы определенно хотите продолжать передавать параметр.
Если вторые две функции будут использоваться только первой функцией, то создание функции / объекта, который оборачивает вещи, было бы хорошим подходом.
var ObjectName = {
var param = null;
function mainFunc(p) {
pararm = p;
func2();
}
function func2() {
// Use "param"
func3();
}
function func3() {
// Use "param"
}
}
// At this level of the code, the param variable is out of scope.
Ответ №7:
Слишком много глобальных переменных — плохая идея: вы потеряете представление о том, что-обслуживать-что.
Слишком много параметров в функции — плохая идея: станет запутанным / трудно вспомнить, какие параметры идут с какими функциями.
Вы могли бы начать с переосмысления вашего дизайна в первую очередь.
Группировка их по объекту, как предложил Александр Гесслер, является хорошей идеей.
Другая идея заключается в создании другой области видимости для вашей функции / переменных… (не обязательно в объекте). Функции в функциях, если вы предпочитаете.
Ответ №8:
Что-то вроде этого было бы хорошо для вас.
var cakes = function() {
// Sets a varable called param1, will use it in the prototype below
this.param1 = 'i like cakes';
// Calls the init prototype, setup below.
this.init();
};
cakes.prototype = {
init: function() {
// this.param1 is set above.
console.log(this.param1);
$.ajax({
// For example I'm just passing back the page which this javascript is in, so something returns
url: window.location.href,
// _this stores the full object, so you can get it in the callback below.
_this: this,
// success calls the ajaxCallback function, below
success: this.ajaxCallback
});
},
ajaxCallback: function() {
// this here refers to the ajax call
console.log(this);
// this._this refers to the original object, captured above.
console.log(this._this);
// this._this.param1 refers to the text set above.
console.log(this._this.param1);
}
};
// Make sure you include this or it won't work
var x = new cakes();
// or you could just do this if you are only planning on using one instance of this object on a page.
// new cakes();
Ответ №9:
Не бойтесь использовать частные переменные, вот краткий пример на jsbin. Это может не соответствовать тому, что вам нужно, но важно принять к сведению, что вы не всегда выбираете между глобальным и параметром. Между ними есть много вариантов.
var MyNamespace = function () {
// private variable
var myPrivateVariable = 'me';
// private methods
var secondFunction = function () { };
// return an object, this becomes MyNamespace
return {
// expose a method called start
start: function (arg1) {
// take the arg and assign it to a private
myPrivateVariable = arg1;
// call a private variable, we can only call / access privates from within the returned object assigned to MyNamespace
secondFunction();
},
// expose a method called third
third: function () {
// alert out our private variable
alert(myPrivateVariable);
}
};
} (); // here we're assigning the result of this function call to MyNamespace and closing around all the privates
// Usage:
MyNamespace.start('me');
MyNamespace.third();
Комментарии:
1. Глобальное состояние обычно плохое, даже если оно частное.
2. Вопрос настолько расплывчатый, что вы не можете сказать, для чего он его использует. Также, что это за оператор? Если это частное, то оно не глобальное. Я имею в виду, я предполагаю, что состояние будет «глобальным» для любой конкретной единицы измерения. В данном случае, 1 экземпляр простого объекта. Будут случаи, когда это уместно, а когда и нет.
3. Потому что он использует асинхронные вызовы ajax. И в сценарии с асинхронным вызовом ajax можно вызвать
start()
дважды с разными значениями, таким образом переопределяя заданноеarg1
из первого вызова передthird
вызовом.4. Ах, я не включил это в свой пример, потому что предположил, что он просто добавил это для демонстрационных целей
Ответ №10:
Передача параметра через является абсолютно разумным и фактически единственным возможным способом, если у вас есть асинхронный вызов ajax. Вы не можете гарантировать, что глобальная переменная может быть перезаписана другим вызовом start(), пока ajax не вызовет обратный вызов первого вызова start().