“var FOO = FOO || {}”(변수 또는 해당 변수에 빈 개체 할당)는 Javascript에서 의미합니까?


99

온라인 소스 코드를 살펴보면 여러 소스 파일 상단에서 이것을 발견했습니다.

var FOO = FOO || {};
FOO.Bar = …;

그러나 나는 무엇을하는지 전혀 모른다 || {}.

나는 그것이 {}같다는 것을 알고 new Object()있고 나는 ||"이미 존재한다면 그 가치를 사용하고 그렇지 않으면 새로운 객체를 사용하라.

소스 파일의 맨 위에 왜 이것을 볼 수 있습니까?


참고 :이 질문은 Javascript 소스 파일 상단에서 일반적으로 볼 수있는 코드 패턴임을 반영하여 편집되었습니다.
Robert Harvey

답변:


153

의 의도에 대한 귀하의 추측 || {}은 매우 가깝습니다.

파일 상단에서 볼 때이 특정 패턴은 네임 스페이스 , 즉 전역 객체를 부당하게 오염시키지 않고 함수와 변수를 만들 수있는 명명 된 객체 를 만드는 데 사용됩니다 .

그 이유 이유 는 사용의 너무입니다 당신이 파일을 두가 (또는 그 이상)의 경우 :

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func1 = {
}

var MY_NAMESPACE = MY_NAMESPACE || {};
MY_NAMESPACE.func2 = {
}

둘 다 동일한 네임 스페이스를 공유하므로 두 파일이로드되는 순서는 중요하지 않습니다 . 객체 내에서 올바르게 정의 func1되고 func2올바르게 정의 MY_NAMESPACE됩니다.

로드 된 첫 번째 파일 은 초기 개체 를 만들고MY_NAMESPACE 이후에로드 된 파일은 개체 를 증가 시킵니다.

유용하게도 이는 동일한 네임 스페이스를 공유하는 스크립트의 비동기 로드를 허용 하여 페이지로드 시간을 개선 할 수 있습니다. 는 IF <script>태그가 가지고있는 defer속성은있는 그들이 그렇게으로 그 문제도이 수정 위의 설명, 해석됩니다 주문 알 수 없다 설정합니다.


2
이것은 정확히 사실입니다. 처음에 똑같은 선언을 가진 몇 개의 js 파일이 있습니다. 감사합니다!
Ricardo Sanchez

41
+1 줄 사이를 읽고 그 이유를 설명합니다. 사용자가 요청한 것보다 실제로 원하는 답을 누군가가 제공 할 때 항상 좋습니다 . :)
Spudley 2011-06-22

1
내가 / # 자바 스크립트에 대해 정의 IFNDEF이 :)이 #의 말씀을 전합니다
대런 코프

1
||선택적 인수를 제공하고 제공되지 않은 경우 기본값으로 초기화하려는 경우에도 매우 유용합니다.function foo(arg1, optarg1, optarg2) { optarg1 = optarg1 || 'default value 1'; optarg2 = optart2 || 'defalt value 2';}
crazy2be

1
@ crazy2be는 기본값이 진실이면 작동하지 않지만 ||연산자가 undefined에서 말할 수 없기 때문에 거짓 값도 합법적 입니다 falsey.
Alnitak

23
var AEROTWIST = AEROTWIST || {};

기본적으로이 줄은 AEROTWIST변수를 변수 값으로 AEROTWIST설정하거나 빈 객체로 설정하는 것입니다.

이중 파이프 ||는 OR 문이며 OR의 두 번째 부분은 첫 번째 부분이 false를 반환하는 경우에만 실행됩니다.

따라서 AEROTWIST이미 값이있는 경우 해당 값으로 유지되지만 이전에 설정되지 않은 경우 빈 개체로 설정됩니다.

기본적으로 다음과 같이 말하는 것과 같습니다.

if(!AEROTWIST) {var AEROTWIST={};}

도움이 되었기를 바랍니다.


1
실제로 JS에는 블록 범위가
Alnitak 2011-06-22

@Alnitak-meh, 맞아요. 최근 클로저 작업을 너무 많이해서 기본 사항을 잊어 버렸습니다. 답을 수정하겠습니다.
Spudley 2011-06-22

6

||에 대한 또 다른 일반적인 용도 정의되지 않은 함수 매개 변수에 대한 기본값을 설정하는 것입니다.

function display(a) {
  a = a || 'default'; // here we set the default value of a to be 'default'
  console.log(a);
}

// we call display without providing a parameter
display(); // this will log 'default'
display('test'); // this will log 'test' to the console

일반적으로 다른 프로그래밍에서 동등한 것은 다음과 같습니다.

function display(a = 'default') {
  // ...
}

당신은 필요하지 않습니다 var앞에 a, aA와 함수의 실행 컨텍스트를 입력 형식 매개 변수 따라서 이미 선언.
Fabrício Matté 2013

6

var FOO = FOO || {};다루는 두 가지 주요 부분이 있습니다.

# 1 재정의 방지

코드를 여러 파일로 분할하고 동료도 FOO. 그러면 누군가 이미 FOO기능을 정의 하고 할당 한 경우 (예 : skateboard기능)로 이어질 수 있습니다 . 그런 다음 이미 존재하는지 확인하지 않으면 재정의합니다.

문제가있는 경우 :

// Definition of co-worker "Bart" in "bart.js"
var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker "Homer" in "homer.js"
var FOO = {};

FOO.donut = function() {
  alert('I like donuts!');
};

이 경우 skateboard당신은 자바 스크립트 파일을로드하는 경우 기능은 사라질 것입니다 homer.jsbart.js호머가 새로운 정의 때문에 HTML에 FOO객체를 (따라서 바트에서 기존보다 우선) 그것은 단지에 대해 알 수 있도록 donut기능.

따라서 var FOO = FOO || {};"FOO가 FOO (이미 존재하는 경우)에 할당되거나 새 빈 개체 (FOO가 이미 존재하지 않는 경우)에 할당된다는 의미 를 사용해야 합니다.

해결책:

var FOO = FOO || {};

// Definition of co-worker Bart in bart.js
FOO.skateboard = function() {
  alert('I like skateboarding!');
};

// Definition of co-worker Homer in homer.js
var FOO = FOO || {};

FOO.donut = function() {
  alert('I like donuts!');
};

바트와 호머 지금의 존재 여부를 확인하기 때문에 FOO그들의 방법을 정의하기 전에, 당신은로드 할 수 있습니다 bart.jshomer.js(서로 다른 이름이있는 경우) 서로 다른 방법을 무시하지 않고 임의의 순서로한다. 그래서 당신은 항상 FOO메소드 skateboarddonut(Yay!)를 가진 객체를 얻을 것 입니다.

# 2 새 개체 정의

첫 번째 예제를 읽었다면 이미 || {}.

기존 FOO개체 가 없으면 OR 케이스가 활성화되고 새 개체가 생성되므로 여기에 기능을 할당 할 수 있습니다. 처럼:

var FOO = {};

FOO.skateboard = function() {
  alert('I like skateboarding!');
};

3

AEROTWIST에 값이 없거나 null이거나 정의되지 않은 경우 새 AEROTWIST에 할당 된 값은 {} (빈 개체)입니다.


1

||오퍼레이터는 두 개의 값을 취

a || b

a가 진실 이면 반환 a됩니다. 그렇지 않으면을 반환 b합니다.

falsy 값은 null, undefined, 0, "", NaNfalse. 진실 된 가치는 그 밖의 모든 것입니다.

따라서 a설정되지 않은 경우 ( undefined그 것인지) 반환 b됩니다.


잘 모르겠어요 truthyfalsey는 실제 단어로 영속되어야한다. 재미 있지만 표준은 아닙니다. :-)
Orbling

4
@Orbling 그들은 JS에서 이러한 값에 대해 이야기하는 데 매우 일반적으로 사용됩니다.
Alnitak 2011-06-22

+1은 논리 연산자가 아니므로 연산자를 올바르게 설명합니다. 때로는 "기본 연산자"라고합니다.
Tim Büthe 2011-06-22

@Tim ||JS (및 Perl)와 C, C ++ 및 Java 버전 의 유일한 차이점은 JS가 결과를 부울로 변환하지 않는다는 것입니다. 여전히 논리 연산자입니다.
Alnitak

@Alnitak : 아마도 과거의 JS 개발자의 비전문적 인 배경 때문일 것입니다.
Orbling

-1

일부 버전의 IE에서는이 코드가 예상대로 작동하지 않습니다. 때문에 var, 변수는 재정의 하고 있으므로 할당 - 나는 문제를 올바르게 기억하는 경우 - 당신은 항상 새로운 객체를 가지고 될 겁니다. 그러면 문제가 해결됩니다.

var AEROTWIST;
AEROTWIST = AEROTWIST || {};
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.