자바 스크립트는 정의되지 않은 경우 변수를 설정


172

자바 스크립트 변수를 테스트 한 다음 정의되지 않은 경우 변수를 정의 할 수는 있지만 말할 방법이 없습니다.

var setVariable = localStorage.getItem ( 'value') || 0;

훨씬 더 분명한 방법으로 보입니다. 다른 언어로 보았을 것입니다.


30
입니다 하지 "정의되지 않은"에 대한 테스트, 그것은 "falsey"에 대한 테스트입니다
알니 타크

3
참고 localStorage.getItem()사용자가 (크롬에 적어도) 장애인 쿠키가있는 경우 당신이 내부를 포장 할 수 있도록 예외가 발생합니다 try...catch
urish

답변:


304

예, 그렇게 할 수는 있지만 실제로는 undefined 와 반대로 검색 된 값이 false 인 경우 기본값을 지정합니다 . 따라서에만 일치하지 않을 뿐만 아니라 , , , , (하지만 하지 ).undefinednullfalse0NaN"" "0"

변수가 엄격 할 경우에만 기본값으로 설정 undefined하려면 가장 안전한 방법은 다음과 같습니다.

var x = (typeof x === 'undefined') ? your_default_value : x;

최신 브라우저에서는 실제로 작성하는 것이 안전합니다.

var x = (x === undefined) ? your_default_value : x;

그러나 undefined정의 된 값을 가진 변수를 선언 할 수있는 이전 브라우저에서는이를 파괴 하여 테스트에 실패 할 수 있습니다.


3
이 패턴이 더 많은 JS 라이브러리에 포함되지 않은 것에 놀랐습니다.
joemaller 2013

var x = (x === undefined ? def_val : x);약간 더 길게 사용하면 단점이 있습니까 var x = (typeof x === 'undefined') ? def_val : x;? 행동이 다릅니 까?
Marco Pashkov

3
이전 버전의 브라우저에서는 @marco를 undefined다시 정의하여 동등성 테스트에 실패했습니다.
Alnitak

@Alnitak OP가 사용하는 구문과 유사한 구문을 사용하고 정의되지 않은 것을 확인하는 가장 좋은 방법은 무엇입니까?
Ivo Pereira

@IvoPereira ||정의되지 않은 엄격한 테스트 에서는이 방법을 사용할 수 없으며 undefined조건부와 함께 명시적인 테스트를 사용해야합니다 .
Alnitak

26

2018 ES6 답변은 다음과 같습니다.

return Object.is(x, undefined) ? y : x;

변수 x가 정의되지 않은 경우 변수 y를 반환합니다. 그렇지 않으면 변수 x가 정의 된 경우 변수 x를 반환합니다.


4
내가 알 수있는 한, 이 경우 Object.is보다 낫지 않습니다 ===. "=== 연산자 (및 == 연산자도)는 숫자 값 -0과 +0을 동일하게 취급하고 Number.NaN을 NaN과 동일하지 않은 것으로 취급합니다." ( developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… ) 여기서 중요하지 않습니다.
Trevor Dixon

5
동의하지 않습니다. 둘 다 알고 적절한 것을 사용하십시오. 특히 Object.is두 피연산자가 모두 인 경우 사용 하십시오 NaN.
Trevor Dixon

2
Object.is ()가 사용 사례의 100 %에서 작동하고 === 사용 사례의 98 %에서 작동하는 경우 왜 ===를 사용하는 위험이 있습니까? 예를 들면 다음과 같습니다. console.log (+0 === -0); // true를 출력하는 동안 console.log (Object.is (+0, -0)); // false를 출력합니다. 어느 것이 더 낫습니까? 음수 0은 양수 0과 동일합니까? 그것은 당신이 스스로에게 물어봐야 할 질문이지만, Object.is ()를 사용한다면 항상 답을 알고 있습니다. 그것들은 같지 않으므로 false 출력은 정확하고 예상되는 결과입니다.
Sterling Bourne

2
여기의 특정 문맥은 항상와 비교합니다 undefined. 그래서 ===시간의 100 % 아닌 98 %를 작동합니다. ===읽기 쉽고, 특히 한 눈에 더 짧고, 불필요한 메소드 호출을 피할 수 있다는 장점이 있습니다. 개인적으로 Object.is()상황이 필요할 때만 사용 ===하고 다른 모든 경우를 선호합니다 .
blubberdiblub

1
물론; 숙련 된 코더라면 실수로 등호를 잊어 버리지 않는 한, ==가 어딘가에서 작동하지 않는 이유를 디버깅하는 것은 어떤 개발자에게도 바람직하지 않은 것입니다. 죄송합니다. 안전하고 항상 Object.is ()를 사용하십시오. 스펙에 포함 된 이유는 개발자가 버그가 적은 코드를 작성하는 데 도움을주기위한 것입니다.
Sterling Bourne

7

여러 곳에서 "정의되지 않은 경우 변수를 설정"해야했습니다. @Alnitak 답변을 사용하여 함수를 만들었습니다. 잘만되면 그것은 누군가를 돕는다.

function setDefaultVal(value, defaultValue){
   return (value === undefined) ? defaultValue : value;
}  

용법:

hasPoints = setDefaultVal(this.hasPoints, true);

6

typeof대신 확인 하는 것이 더 논리적 인 것 같습니다 undefined. 0정의되지 않은 경우 var을 설정하면 숫자가 필요하다고 가정합니다 .

var getVariable = localStorage.getItem('value');
var setVariable = (typeof getVariable == 'number') ? getVariable : 0;

이 경우 getVariable숫자 (문자열, 객체 등)가 아닌 경우 setVariable은0


5

ES2020 답변

으로 Nullish 합체 경우 운영자, 당신은 기본 값을 설정할 수 있습니다 valuenull 또는 정의되지 않은입니다.

const setVariable = localStorage.getItem('value') ?? 0;

그러나 Nullish 통합 연산자는 0and 같은 다른 유형의 잘못된 값에 대한 기본값을 반환하지 않습니다 ''.

운영자에 대한 브라우저 지원은 제한되어 있습니다. caniuse 의 데이터에 따르면 , 2020 년 4 월 기준으로 브라우저의 48.34 % 만 지원됩니다. Node.js 지원은 버전 14추가되었습니다 .


2

FP ( Functional Programming ) 팬이라면 RamdadefaultTo 라는 깔끔한 도우미 기능을 가지고 있습니다 .

용법:

const result = defaultTo(30)(value)

undefined부울 값을 처리 할 때 더 유용 합니다.

const result2 = defaultTo(false)(dashboard.someValue)


1
이것은 const result = value || 30;중간 함수와 +1000 바이트를 사용하는 것을 제외하고 는 정확히 입니다 – lib
Adelin

1
@Adelin은 사실이 아니며 부울 유형에 대한 잘못된 처리도 수행합니다. 이 라이브러리를 이미 사용하고 있다면 (그대로) 매우 유용하고 간결합니다
Damian Green

1

var setVariable = (typeof localStorage.getItem('value') !== 'undefined' && localStorage.getItem('value')) || 0;


또한 0 asign하지 않을 경우 localStorage.getItem('value'))반환false
칼 애들러

1

오늘이 시나리오를 살펴 보았고 여러 값으로 0을 덮어 쓰지 않으려 고했습니다. 우리는 이와 같은 시나리오를위한 일반적인 유틸리티 방법을 가진 파일을 가지고 있습니다. 시나리오를 처리하고 유연하게하기 위해 추가 한 내용은 다음과 같습니다.

function getIfNotSet(value, newValue, overwriteNull, overwriteZero) {
    if (typeof (value) === 'undefined') {
        return newValue;
    } else if (value === null && overwriteNull === true) {
        return newValue;
    } else if (value === 0 && overwriteZero === true) {
        return newValue;
    } else {
        return value;
    }
}

정의되지 않은 값으로 만 설정하거나 null 또는 0 값을 덮어 쓰려면 마지막 두 매개 변수를 선택 사항으로 호출 할 수 있습니다. 다음은 ID가 정의되지 않았거나 null 인 경우 0을 덮어 쓰지 않는 경우 ID를 -1로 설정하는 호출 예입니다.

data.ID = Util.getIfNotSet(data.ID, -1, true);

1

우리 시대에는 실제로 JS로 접근 할 수 있습니다.

// Your variable is null
// or '', 0, false, undefined
let x = null;

// Set default value
x = x || 'default value';

console.log(x); // default value

따라서 귀하의 예는 효과가 있습니다.

const setVariable = localStorage.getItem('value') || 0;

0

기본값이 부울 값인 경우에도 작동합니다.

var setVariable = ( (b = 0) => b )( localStorage.getItem('value') );

0

현재 자바 스크립트 구현의 경우

var [result='default']=[possiblyUndefinedValue]

이 작업을 수행하는 좋은 방법입니다 (객체 분해 사용).


0

논리적 인 무효 할당, ES2020 + 솔루션

신규 사업자는 현재 브라우저에 추가되고 ??=, ||=하고 &&=. 이 게시물은에 초점을 맞출 것입니다 ??=.

왼쪽이 정의되어 있지 않은지 확인하고 이미 정의 된 경우 단락을 검사합니다. 그렇지 않으면 오른쪽이 왼쪽 변수에 할당됩니다.

방법 비교

// Using ??=
name ??= "Dave"

// Previously, ES2020
name = name ?? "Dave"

// Before that (not equivalent, but commonly used)
name = name || "Dave" // name ||= "Dave"

기본 예

let a          // undefined
let b = null
let c = false

a ??= true  // true
b ??= true  // true
c ??= true  // false

// Equivalent to
a = a ?? true

객체 / 배열 예

let x = ["foo"]
let y = { foo: "fizz" }

x[0] ??= "bar"  // "foo"
x[1] ??= "bar"  // "bar"

y.foo ??= "buzz"  // "fizz"
y.bar ??= "buzz"  // "buzz"

x  // Array [ "foo", "bar" ]
y  // Object { foo: "fizz", bar: "buzz" }

?? = 브라우저 지원 2020 년 7 월-.03 %

?? = Mozilla 문서

|| = 모질라 문서

&& = Mozilla 문서


이 두 질문에 대한이 답변을 복사하는 것은 좋은 생각이 정말 ( 경우는 null 값을 교체하거나 자바 스크립트에서 정의되지 않은자바 스크립트의 연산자는 "병합 널 (null)"는 있습니까? )? 의견에서 중복 된 내용이나 관련 질문에 대한 링크로 VTC보다 낫지 않습니까?
user4642212

질문은 모두 약간 다릅니다. 따라서 답변도 마찬가지입니다. 예제는 인라인 컨텍스트를 한 눈에 개선하기 위해 일관성이 있습니다. 아마도 더 자세한 정보를 위해 연결되었을 수도 있지만 사람들이 솔루션을 건너 뛸 수있는 추가 홉이 필요했을 것입니다.
Gibolt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.