program story

전역 변수가 나쁘다고 들었습니다. 어떤 대체 솔루션을 사용해야합니까?

inputbox 2020. 10. 31. 09:40
반응형

전역 변수가 나쁘다고 들었습니다. 어떤 대체 솔루션을 사용해야합니까?


나는 전역 변수가 나쁘고 대안을 사용해야한다는 것을 모든 곳에서 읽었습니다 . 특히 Javascript에서는 어떤 솔루션을 선택해야합니까?

두 개의 인수 ( function globalVariables(Variable,Value))를 입력하면 변수가 로컬 배열에 존재하는지 Value, Variable그리고 값을 , else로 설정 하고 Value추가 되는 함수를 생각 하고 있습니다. 인수 ( function globalVariables()) 없이 함수를 호출 하면 배열을 반환합니다. 아마도 함수가 하나의 인수 ( function globalVariables(Variable)) Variable로 시작되면 배열 의 값을 반환합니다 .

어떻게 생각해? 전역 변수 사용에 대한 대체 솔루션과 주장을 듣고 싶습니다.

사용 방법 globalVariables();

function append(){
    globalVariables("variable1","value1"); //globalVariables() would append variable1 to it's local array.
};

function retrieve(){
    var localVariable1 = globalVariables("variable1"); //globalVariables() would return "value1".
};

function retrieveAll(){
    var localVariable1 = globalVariables(); //globalVariables() would return the globalVariable()'s entire, local [persistently stored between calls] array.
};

function set(){
    globalVariables("variable1","value2"); //globalVariables() would set variable1 to "value2".
};

이것은가 싱글 톤 패턴 BTW?

이 특정 시나리오에서 함수는 한 시점에서 변수를 설정할 수 있으며 훨씬 나중에 사용자가 양식을 제출할 때 다른 함수가 해당 변수를 가져와야합니다. 따라서 첫 번째 함수는 첫 번째 함수에서 호출되지 않으므로 변수를 나중 함수의 인수로 전달할 수 없습니다.

감사합니다. 모든 도움에 감사드립니다!


자바 스크립트에서 전역 변수가 권장되지 않는 주된 이유는 자바 스크립트에서 모든 코드가 단일 전역 네임 스페이스를 공유하고 자바 스크립트도 전역 변수를 암시하기 때문입니다. 로컬 범위에서 명시 적으로 선언되지 않은 변수는 자동으로 전역 네임 스페이스에 추가됩니다. 전역 변수에 너무 많이 의존하면 같은 페이지의 다양한 스크립트간에 충돌이 발생할 수 있습니다 ( Douglas Crockford의 기사 읽기 ).

전역 변수를 줄이는 한 가지 방법은 YUI 모듈 패턴 을 사용하는 것 입니다 . 기본 아이디어는 모듈 외부에서 액세스해야하는 함수를 포함하는 객체를 반환하는 함수로 모든 코드를 래핑하고 반환 값을 단일 전역 변수에 할당하는 것입니다.

var FOO = (function() {
    var my_var = 10; //shared variable available only inside your module

    function bar() { // this function not available outside your module
        alert(my_var); // this function can access my_var
    }

    return {
        a_func: function() {
            alert(my_var); // this function can access my_var
        },
        b_func: function() {
            alert(my_var); // this function can also access my_var
        }
    };

})();

이제 다른 곳에서 모듈의 함수를 사용하려면 FOO.a_func(). 이 방법으로 전역 네임 스페이스 충돌을 해결하려면 FOO.


의미론 내 아들. 의미론.

하나의 글로벌로 시작 : myApp = {}; 모든 것이 그 안에 있어야합니다. 유일한 예외는 AJAX 라이브러리입니다 (JSONP 콜백 작업과 같은 몇 가지 극단적 인 예외가 있습니다).

myApp에는 속성이 거의 없어야합니다. 구성 또는 설정과 같은 컨테이너에 애플리케이션 속성을 보유하고 싶을 것입니다.

myApp = {
    config:{
        prop:1
    },
    settings:{
        prop:2
    },
    widgets:{
        List: function(props){},
        Item: function(props){}
    }
}

그러면 하위 모듈, 구성 요소, 싱글 톤 및 클래스 생성자 (위젯)에 더 많은 속성이있을 수 있습니다.

이 설정은 myApp 전역에서 얻을 수 있기 때문에 다른 위치에서 모든 속성에 액세스 할 수 있다는 추가 이점을 제공합니다. 그러나 조회가 더 빠르기 때문에 가능하면 "this"를 사용해야합니다. 그리고 속성을 직접 설정하고 의사 getter / setter 항목에 신경 쓰지 마십시오. getter / setter가 정말로 필요한 경우 특정 용도로 코딩하십시오.

귀하의 예제가 작동하지 않는 이유는 너무 일반적이고 글로벌 공간에서 일할 변명을 찾고있는 것 같습니다.

그리고 개인 변수에 대해 영리하지 마십시오. 그들도 나쁘다 : http://clubajax.org/javascript-private-variables-are-evil/


글로벌 상태는 여러 영역에서 문제를 일으 킵니다. 하나는 코드 재사용입니다. 일부 전역 상태에 액세스하면 구성 요소가 자신의 환경 (자체 외부의 것)을 인식해야합니다. 구성 요소를 예측할 수 없게하므로 가능한 한 피해야합니다.

globalVariables 함수에 액세스하는 개체가 있고 다른 페이지에서 사용하고 싶습니다. globalVariables 객체를 정의하는 방법 또는 정의하는 방법을 어떻게 알 수 있습니까? 그러나 정보를 생성자 또는 함수에 대한 인수로 전달할 수 있다면 객체에 필요한 것을 쉽게 결정할 수 있습니다.

또한 전역 범위에 액세스하거나 수정하면 다른 개체에 영향을 미칠 위험이 있습니다. 이것이 jquery와 같은 라이브러리가 전역 범위에서 단일 이름 만 사용하는 이유입니다 (최소한 가능). 다른 라이브러리와의 충돌 가능성을 줄입니다. 즉, 전역 범위는 제어 할 수 없으므로 위험합니다.


당신은 정말로 이것을하고 싶지 않습니다.
그 이유에 대해서는 여기의 최상위 게시물을 참조하십시오. 프로덕션 엔터프라이즈 환경에서 본 가장 악의적 인 코드는 무엇입니까?

참고로, 전역으로 장소를 흩 뜨리지 않고 항상 "전역"코드를 실행할 수 있습니다.

(function () {
    var notaglobal = 1;
    alert(notaglobal);
})();
//notaglobal is not defined in this scope        

전역 변수를 사용하는 것은 일반적으로 선택한 언어에 관계없이 나쁜 습관을 말합니다. 엄격 모드 에서는 (쉽게) 사용할 수 없으므로 강력히 권장합니다.

내가 찾은 다음 코드를 고려하십시오.

if (typeof session != 'undefined' && !data.cart.request_status)
  data.input_definitions.passengers =
    inflate_passenger(session, data.input_definitions.passengers);

나는 돌아 서서이 session변수가 어디에서 왔는지 물어볼 필요가 있었다. 설정된 곳에서 코드 검색이 나타나지 않았기 때문이다.

나는 회사의 또 다른 패키지가 전역 변수를 설정하는 것으로 나타났습니다. 코드는 농담과 같습니다. 설명 할 필요가 있다면 그다지 좋지 않을 것입니다.

ES6를 사용한 해결 방법 :

노드, 사용의 경우 import또는 require어휘 범위에 원하는 물건을 가지고, 사람들이 당신이 그것을 알고하지 않고 지구 환경을 만지게하지 않습니다.

import {Sesssion} from 'api-core';
const Session = require('api-core').session;

브라우저 용 코드를 전달하는 프런트 엔드에있는 경우 Babel을import 사용하여 ES6 코드를 트랜스 파일하지 않는 한 사용할 수 없습니다 .

Gulp.js를 사용한 트랜스 파일 예제 :

// $ npm install --save-dev gulp-babel babel-preset-es2015

// gulpfile.js
const gulp  = require('gulp');
const babel = require('gulp-babel');

gulp.task('transpile', () => {
  return gulp.src('src/app.js')
    .pipe(babel({presets: ['es2015']}))
    .pipe(gulp.dest('dist'));
});

// $ gulp transpile

레거시 해결 방법 :

When using ES6 features is not an option the only workaround to using a bunch of global variables, is using only one, and have hope:

// scripts/app.js
var MyApp = {
  globals: {
    foo: "bar",
    fizz: "buzz"
  }
};

The issue with your solution is that it just makes you code harder to understand while still keeping all the downsides of global variables. The page you linked to covers the problems. The only problem your proposed solution really solves is namespace pollution but at the cost of not being able to see what global variables are declared as easily as the declaration is a function call).

The solution is to write code without global variables. If a function needs a value pass it as a argument.


Other answer most explain with anonymous function as this article mention,

Anonymous functions are difficult to debug, maintain, test, or reuse.

Here are example with normal function. It's easier to read and understand.

/* global variable example */

    var a= 3, b= 6;
    
    function fwithglobal(){
    console.log(a, b); // 3 6 expected
    }
    
    fwithglobal(); // first call
    
    function swithglobal(){
    var a=9;
    console.log(a, b); // not 3 6 but 9 6
    }
    
    swithglobal(); // second call
    

/* global variable alternative(function parameter) */

    function altern(){
    var a= 3, b= 6; // var keyword needed
      f_func(a,b);
      s_func(a,b);
    }
    
    function f_func(n, m){
    console.log(n, m); // 3 6 expected
    }
    
    function s_func(n, m){
    var a=9;
    console.log(n, m); // 3 6 expected
    }
    
    altern(); // only once


var ASHIVA_HandsOffNHS = (function() {
    
    // VARIABLES

    var my_var = 10;


    // PRIVATE FUNCTIONS
    
    function bar() {
        window.alert(my_var + 5);
    }


   // PUBLIC OBJECT

    myObject = {};
    
    myObject['a_func'] = function() {
            my_var += 10;
            window.alert(my_var);
        };
        
    myObject['b_func'] = function() {
            my_var = 0;
            window.alert(my_var);
        };

    return myObject;

})();

ASHIVA_HandsOffNHS.a_func();
ASHIVA_HandsOffNHS.b_func();
ASHIVA_HandsOffNHS.a_func();


Global variables are bad... if left unmanaged!

The potential risks of global variables is as high as the pleasure and productivity gains of having frequently used objects ready to use.

I don't believe one should seek a single alternative. Instead I advocate for one object in charge of managing those globals and as the code base/component matures, refactor them out

One thing not mentioned in the current answers which I think is critical is an understanding of DI and IoC containers. These address many of the problems people try to solve with global variables, but covering related concerns that plain globals can't, like object life cycles.

참고URL : https://stackoverflow.com/questions/2613310/ive-heard-global-variables-are-bad-what-alternative-solution-should-i-use

반응형