это плохая практика для параметров через строку функций? - PullRequest
4 голосов
/ 01 июня 2011

Я создаю достаточно большое 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);
}

Итак, вы бы сказали, что передача параметров через болееодна функция в порядке или я должен делать это по-другому?

Спасибо

Ответы [ 10 ]

7 голосов
/ 01 июня 2011

На самом деле, это хорошая практика, потому что она позволяет избежать какого-либо глобального состояния (т. Е. В идеале поведение функции будет зависеть только от ее параметров).

Если у вас есть много параметров, которые будут переданы таким способом, я бы собрал их вместе в отдельный объект (объект «окружение»), но, кроме того, это совершенно нормально.

Делая это таким образом, вы получаете большую гибкость - если вы хотите, чтобы функция работала с разными данными один раз, вы просто передаете разные значения, а не изменяете глобальное состояние, что может повлиять на все остальное.Также (отсутствие таких глобальных побочных эффектов делает распараллеливание функций очень простым, даже если это не так важно для JavaScript).

1 голос
/ 01 июня 2011

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

Поскольку 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'});
1 голос
/ 01 июня 2011

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

Например, он позволяет запускать процесс несколько раз, не портя глобальное состояние.

0 голосов
/ 01 июня 2011

Не бойтесь использовать приватные переменные, вот быстрый пример на 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();
0 голосов
/ 01 июня 2011

Что-то вроде этого было бы хорошо для вас.

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();
0 голосов
/ 01 июня 2011

Слишком много глобальных переменных - плохая идея: вы потеряете представление о том, что служит.

Слишком много параметров в функции - это плохая идея: становится запутанным / трудно вспомнить, какие параметры соответствуют каким функциям.

Вы могли бы начать сначала с переосмысления своего дизайна.

Группировать их по объектам, как предположил Александр Гесслер, - хорошая идея.

Другая идея - создать другую областьдля вашей функции / переменных ... (не обязательно в объекте).Функции в функциях, если вы предпочитаете.

0 голосов
/ 01 июня 2011

Это довольно сложный вопрос для ответов, поскольку все зависит от поставленной задачи.

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

Если вторые две функции только когда-либо используются первой функцией, то хорошим решением будет создание функции / объекта, оборачивающего вещи.

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.
0 голосов
/ 01 июня 2011

В javascript есть особый способ для области видимости переменных, в первом примере вы определяете param1 при запуске, поэтому все потоки и функции, которые были вызваны и в контексте функций запуска, имеют переменную param1, которая «наследуется» дляпозвонить каким-нибудь образом.поэтому все операторы, используемые вне start, не имеют определенной переменной param1.Таким образом, вам нужно использовать эту область видимости переменной, только когда вам нужно использовать переменную в потоке или серии функций с именем.

во втором примере используется область видимости глобальной переменной, это означает, что переменная используется сглобальное значение независимо от того, какой поток вы вызвали, это применимо только в том случае, если вы не определяете снова param1 в другом контексте.

, поэтому все зависит от того, что вы собираетесь делать, в приведенном выше примере эффективность Mosstвторой

0 голосов
/ 01 июня 2011

Передача параметра является вполне разумной и фактически единственным возможным способом, если у вас есть асинхронный вызов ajax.Вы не можете гарантировать, что глобальная переменная может быть перезаписана другим вызовом start (), пока ajax не вызовет обратный вызов первого вызова start ().

0 голосов
/ 01 июня 2011

Я не вижу ничего плохого ни в одном стиле.Способ предпочтения здесь, на самом деле.

Единственный недостаток глобалов состоит в том, что они остаются в памяти на всю жизнь приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...