JavaScript isset () 해당


553

PHP에서는 할 수 있습니다 if(isset($array['foo'])) { ... }. JavaScript에서는 종종 if(array.foo) { ... }같은 작업을 수행하지만, 정확히 같은 문장은 아닙니다. 조건은 다음과 같은 경우에도 거짓으로 평가됩니다.array.foo 존재하지만 false또는0 (그리고 아마도 다른 값들도) 입니다.

PHP와 완벽하게 동등한 것은 무엇입니까? issetJavaScript에서 ?

넓은 의미에서, 존재하지 않는 변수, 값이없는 변수 등에 대한 JavaScript의 처리에 대한 일반적이고 완전한 가이드는 편리합니다.


1
내가 객체 속성 쿼리에 상관없이 깊이의 존재를 테스트하는 함수 작성 : stackoverflow.com/a/12681101/1268003을 이 스레드에서 @CMS가 공유하는 지식과 결합 내 코드를 사용하여, 당신은 쉽게 전역을 쓸 수 있습니다 PHP : s isset과 매우 유사한 기능을합니다.
Martin Andersson

3
당신이 사용하는 경우 Underscore.js 시도_.isUndefined(arr.foo)
Vitalii Fedorenko을

옵션 체인은 아마도 대부분의 사람들이 찾고있는 것입니다. stackoverflow.com/a/60845999/2100372
zoran404

답변:


938

나는 일반적으로 typeof연산자를 사용합니다 :

if (typeof obj.foo !== 'undefined') {
  // your code here
}

돌아올 것이다 "undefined"속성이 존재하지 않거나 그 값이 인 경우 합니다 undefined.

(참조 : 차이점undefined 정의 및 정의되지 않음의 )

hasOwnProperty메서드 와 같이 개체에 속성이 있는지 확인하는 다른 방법이 있습니다 .

if (obj.hasOwnProperty('foo')) {
  // your code here
}

그리고 in연산자 :

if ('foo' in obj) {
  // your code here
}

마지막 두 가지의 차이점은 hasOwnProperty메서드가 속성이 존재하는지 확인 한다는 것입니다 객체에 실제로 (속성이 상속되지 않음).

in운영자는 프로토 타입 체인, 예를 들면에 도달 할 수있는 모든 속성을 확인합니다 :

var obj = { foo: 'bar'};

obj.hasOwnProperty('foo'); // true
obj.hasOwnProperty('toString'); // false
'toString' in obj; // true

보시다시피 , 메소드를 확인할 때 연산자가 hasOwnProperty리턴 false하고 in리턴 true하면 toString이 메소드는 objform을 상속 하기 때문에 프로토 타입 체인에 정의됩니다 Object.prototype.


23
typeof오히려 사용 하지 if( obj.foo !== undefined )?
매트 볼

7
아 언젠가는 진정한 크로스 브라우저 Javascript를 작성합니다. 그때까지 ...
매트 볼

37
이것의 문제는 더 깊은 속성을 확인하려고 할 때 오류가 발생한다는 것입니다. 예를 들면 다음과 같습니다. obj.thisdoesntexist.foo! == undefined. PHP에서는 isset 또는 비어 있고 안전하게 사용할 수 있습니다.
Enrique

6
IE8에는 "hasOwnPropery"가 없습니다
max4ever

12
정확히 PHP isset($abc->def->ghi->jkl)는 JavaScript typeof연산자 와 달리 예외를 발생시키지 않고 스크립트를 중단하지 않고 허용 합니다. 당신은 같은 것을 사용해야합니다 try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
스티븐 Pribilinskiy

43

오래된 스레드이지만 이에 상응하는 새로운 방법이 있습니다. isset() .

ESNext (2019 년 12 월 4 일)

두 가지 새로운 구문을 통해 isset()기능 사용을 크게 단순화 할 수 있습니다.

문서를 읽고 브라우저 호환성을 염두에 두십시오.

이전 답변

설명은 아래를 참조하십시오. 참고 StandardJS 구문을 사용합니다

사용법 예

// IMPORTANT pass a function to our isset() that returns the value we're
// trying to test(ES6 arrow function)
isset(() => some) // false

// Defining objects
let some = { nested: { value: 'hello' } }

// More tests that never throw an error
isset(() => some) // true
isset(() => some.nested) // true
isset(() => some.nested.value) // true
isset(() => some.nested.deeper.value) // false

// Less compact but still viable except when trying to use `this` context
isset(function () { return some.nested.deeper.value }) // false

답변 기능

/**
 * Checks to see if a value is set.
 *
 * @param {Function} accessor Function that returns our value
 */
function isset (accessor) {
  try {
    // Note we're seeing if the returned value of our function is not
    // undefined
    return typeof accessor() !== 'undefined'
  } catch (e) {
    // And we're able to catch the Error it would normally throw for
    // referencing a property of undefined
    return false
  }
}

설명

PHP

PHP에서는 어떤 깊이에서든 변수를 참조 할 수 있습니다. 배열로 배열이 아닌 항목에 액세스하려고해도 단순 true또는 false다음을 반환합니다 .

// Referencing an undeclared variable
isset($some); // false

$some = 'hello';

// Declared but has no depth(not an array)
isset($some); // true
isset($some['nested']); // false

$some = ['nested' => 'hello'];

// Declared as an array but not with the depth we're testing for
isset($some['nested']); // true
isset($some['nested']['deeper']); // false

JS

JavaScript에서는 자유가 없습니다. JS가 함수에 deeper 래핑하기 전에 값에 즉시 액세스하려고하기 때문에 항상 그렇게하면 오류가 발생합니다 isset().

// Common pitfall answer(ES6 arrow function)
const isset = (ref) => typeof ref !== 'undefined'

// Same as above
function isset (ref) { return typeof ref !== 'undefined' }

// Referencing an undeclared variable will throw an error, so no luck here
isset(some) // Error: some is not defined

// Defining a simple object with no properties - so we aren't defining
// the property `nested`
let some = {}

// Simple checking if we have a declared variable
isset(some) // true

// Now trying to see if we have a top level property, still valid
isset(some.nested) // false

// But here is where things fall apart: trying to access a deep property
// of a complex object; it will throw an error
isset(some.nested.deeper) // Error: Cannot read property 'deeper' of undefined
//         ^^^^^^ undefined

더 실패한 대안 :

// Any way we attempt to access the `deeper` property of `nested` will
// throw an error
some.nested.deeper.hasOwnProperty('value') // Error
//   ^^^^^^ undefined

Object.hasOwnProperty('value', some.nested.deeper) // Error
//                                  ^^^^^^ undefined

// Same goes for typeof
typeof some.nested.deeper !== 'undefined' // Error
//          ^^^^^^ undefined

그리고 중복을 빠르게 얻을 수있는 몇 가지 대안이 있습니다.

// Wrap everything in try...catch
try { isset(some.nested.deeper) } catch (e) {}
try { typeof some.nested.deeper !== 'undefined' } catch (e) {}

// Or by chaining all of the isset which can get long
isset(some) && isset(some.nested) && isset(some.nested.deeper) // false
//                        ^^^^^^ returns false so the next isset() is never run

결론

다른 모든 답변-대부분 실행 가능하지만 ...

  1. 변수가 정의되지 않았는지 확인하고 일부 사용 사례에는 적합하지만 여전히 오류가 발생할 수 있다고 확인한다고 가정하십시오.
  2. 최상위 속성에만 액세스하려고한다고 가정 해 봅시다.
  3. isset()
    예를 들어 PHP에 비해 덜 이상적인 접근 방식을 사용하도록하십시오.isset(some, 'nested.deeper.value')
  4. eval()어떤 작품을 사용 하지만 개인적으로 피하십시오

나는 그것을 많이 덮었다 고 생각합니다. 내 대답에는 내가 관련이 있지만 질문의 일부가 아니기 때문에 다루지 않는 몇 가지 사항이 있습니다. 그러나 필요한 경우 수요에 따라보다 기술적 측면에 대한 링크로 답변을 업데이트 할 수 있습니다.

나는 이것에 많은 시간을 보냈으므로 사람들이 도움이되기를 바랍니다.

읽어 주셔서 감사합니다!


25

소스에 대한 참조

    module.exports = function isset () {
  //  discuss at: http://locutus.io/php/isset/
  // original by: Kevin van Zonneveld (http://kvz.io)
  // improved by: FremyCompany
  // improved by: Onno Marsman (https://twitter.com/onnomarsman)
  // improved by: Rafał Kukawski (http://blog.kukawski.pl)
  //   example 1: isset( undefined, true)
  //   returns 1: false
  //   example 2: isset( 'Kevin van Zonneveld' )
  //   returns 2: true

  var a = arguments
  var l = a.length
  var i = 0
  var undef

  if (l === 0) {
    throw new Error('Empty isset')
  }

  while (i !== l) {
    if (a[i] === undef || a[i] === null) {
      return false
    }
    i++
  }

  return true
}

phpjs.org는 locutus에 찬성하여 대부분 은퇴했습니다. 새로운 링크는 다음과 같습니다 http://locutus.io/php/var/isset


6
정의되지 않은 isset(abc.def.ghi)경우 호출 할 때 예외가 발생 abc.def합니다. 그러나이 솔루션을 문자열 형식의 변수 이름을 허용하는 솔루션과 결합하면 PHP 버전과 동일합니다.
Steven Pribilinskiy 10


8
//
//  tring to reference non-existing variable throws ReferenceError 
//  before test function is even executed
//
//  example, if you do:
//    
//     if ( isset( someVar ) ) 
//        doStuff( someVar );
//   
//  you get a ReferenceError ( if there is no someVar... ) 
//  and isset fn doesn't get executed.
//
//  if you pass variable name as string, ex. isset( 'novar' );, 
//  this might work:
//
function isset ( strVariableName ) { 

    try { 
        eval( strVariableName );
    } catch( err ) { 
        if ( err instanceof ReferenceError ) 
           return false;
    }

    return true;

 } 
//
//


6

필자는 항상이 일반 함수를 사용하여 기본 변수와 배열 및 객체에서 errrors를 방지합니다.

isset = function(obj) {
  var i, max_i;
  if(obj === undefined) return false;
  for (i = 1, max_i = arguments.length; i < max_i; i++) {
    if (obj[arguments[i]] === undefined) {
        return false;
    }
    obj = obj[arguments[i]];
  }
  return true;
};

console.log(isset(obj));                   // returns false
var obj = 'huhu';
console.log(isset(obj));                   // returns true
obj = {hallo:{hoi:'hoi'}};
console.log(isset(obj, 'niet'));           // returns false
console.log(isset(obj, 'hallo'));          // returns true
console.log(isset(obj, 'hallo', 'hallo')); // returns false
console.log(isset(obj, 'hallo', 'hoi'));   // returns true

5

underscorejs 를 사용하는 경우 항상 사용합니다

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}

4

이것은 변수가 존재하는지 테스트하기위한 방탄 솔루션입니다.

var setOrNot = typeof variable !== typeof undefined ? true : false;

불행히도 단순히 함수로 캡슐화 할 수는 없습니다.

다음과 같은 일을 생각할 수 있습니다.

function isset(variable) {
    return typeof variable !== typeof undefined ? true : false;
}

그러나 변수 variable가 정의되지 않은 경우 존재하지 않는 변수를 함수에 전달할 수 없으므로 참조 오류가 발생 합니다.

잡히지 않은 ReferenceError : foo가 정의되지 않았습니다

반면에 함수 매개 변수가 정의되어 있지 않은지 테스트 할 수 있습니다.

var a = '5';

var test = function(x, y) {
    console.log(isset(x));
    console.log(isset(y));
};

test(a);

// OUTPUT :
// ------------
// TRUE
// FALSE

에 대한 값이 비록 y기능에 전달되지 않습니다 test, 우리 isset때문에 기능은 이러한 맥락에서 완벽하게 작동 y기능에 알려진 testint로서 undefined값.


작은 니트 :`? 참 : 거짓은 슈퍼 플로 러스입니다. 결과 !==는 이미 부울입니다.
ToolmakerSteve

4
(typeof SOMETHING) !== 'undefined'

사용할 때 쓰기에 너무 깁니다. 그러나 typeof함수를 호출하기 전에 다음과 같이 오류가 발생하기 때문에 키워드를 함수로 패키지 할 수 없습니다 .

function isdef($var) {
    return (typeof $var) !== 'undefined';
}

isdef(SOMETHING); ///// thrown error: SOMETHING is not defined

그래서 나는 방법을 알아 냈습니다.

function isdef($type) {
    return $type !== 'undefined';
}

isdef(typeof SOMETHING);

개별 변수 (모두 존재하지 않는 변수) 또는 객체 속성 (존재하지 않는 속성)과 함께 작동 할 수 있습니다. 그리고 PHP보다 7 문자 만 더 isset있습니다.


이것은 나를 위해 작동하며 특정 json 응답이 존재하는지 확인하는 데 사용되었습니다.
Julius


3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}

4
설명도 추가하십시오.
슈리 크리슈나

이전의 여러 답변에서 언급했듯이 선언되지 않은 변수로 호출되면 ReferenceError가 발생합니다. 예를 들어 isset(someVar), someVar선언 된 적이없는 곳 입니다. eval그러나을 수행 하면 아마도 문자열 을 전달 하려고합니다 . 사용법을 표시하십시오. 의도 된 사용법 isset('someVar')입니까? 그렇다면 이 이전 답변 과 비슷하게 보입니다. 새로운 답변은 어떻습니까?
ToolmakerSteve


3

html 블록이 존재하는지 여부를 확인하려면이 코드를 사용하고 있습니다.

if (typeof($('selector').html()) != 'undefined') {
    // $('selector') is existing
    // your code here
}

2

객체 경로를 문자열로 제공하면이 문자열을 경로 hasOwnProperty로 나누고 각 반복마다 객체 자체를 덮어 쓰면서 각 단계에서 확인할 수 있습니다 .

ES6 환경에서 코딩하는 경우이 stackoverflow Ques를 살펴보십시오 .

var a;

a = {
    b: {
        c: 'e'
    }
};

function isset (obj, path) {
    var stone;

    path = path || '';

    if (path.indexOf('[') !== -1) {
        throw new Error('Unsupported object path notation.');
    }

    
    path = path.split('.');
    
    do {
        if (obj === undefined) {
            return false;
        }

        stone = path.shift();
        
        if (!obj.hasOwnProperty(stone)) {
            return false;
        }
        
        obj = obj[stone];
        
    } while (path.length);

    return true;
}

console.log(
    isset(a, 'b') == true,
    isset(a, 'b.c') == true,
    isset(a, 'b.c.d') == false,
    isset(a, 'b.c.d.e') == false,
    isset(a, 'b.c.d.e.f') == false
);


2

변수와 객체를 확인할 수있는 함수를 사용합니다. jQuery로 작업하기 매우 편리

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };

이전의 여러 답변에서 언급했듯이 선언되지 않은 변수로 호출되면 ReferenceError가 발생합니다.
ToolmakerSteve

1

객체의 더 깊은 속성에 액세스 할 때 실제로 문제가되었으므로 존재하는 경우 속성 값을 반환하는 함수를 만들었습니다. 그렇지 않으면 false를 반환합니다. 시간을 절약하기 위해 사용할 수 있습니다.

//Object on which we want to test
var foo = {
    bar: {
        bik: {
            baz: 'Hello world'
        }
    }
};


/*
USE: To get value from the object using it properties supplied (Deeper),
    if found it will return the property value if not found then will return false

You can use this function in two ways
WAY - 1:
Passing an object as parameter 1 and array of the properties as parameter 2
EG: getValueFromObject(foo, ['bar', 'bik', 'baz']);
WAY - 2: (This will work only if, your object available in window object)
Passing an STRING as parameter 1(Just similarly how we retrieve value form object using it's properties - difference is only the quote)
EG: getValueFromObject('foo.bar.bik.baz');
*/
function getValueFromObject(object, properties) {
    if(typeof(object) == 'string') {            //Here we extract our object and it's properties from the string
        properties = object.split('.');
        object = window[properties[0]];
        if(typeof(object) == 'undefined') {
            return false;
        }
        properties.shift();
    }
    var property = properties[0];
    properties.shift();
    if(object != null && typeof(object[property]) != 'undefined') {
        if(typeof(object[property]) == 'object') {
            if(properties.length != 0) {
                return getValueFromObject(object[property], properties);    //Recursive call to the function
            } else {
                return object[property];
            }
        } else {
            return object[property];
        }
    } else {
        return false;
    }
}
console.log(getValueFromObject('fooo.bar.bik.baz'));        //false
console.log(getValueFromObject('foo.bar.bik.baz'));         //Hello world
console.log(getValueFromObject('foo'));                     //false
console.log(getValueFromObject('foo.bar.bik'));             //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik']));       //returns an object { baz: 'Hello World' }
console.log(getValueFromObject(foo, ['bar', 'bik', 'baz']));//Hello world

1

요소가 존재하는지 확인하려면 다음 코드를 사용하십시오.

if (object) {
  //if isset, return true
} else {
  //else return false
}

이것은 샘플입니다.

function switchDiv() {
    if (document.querySelector("#divId")) {
        document.querySelector("#divId").remove();
    } else {
        var newDiv = document.createElement("div");
        newDiv.id = "divId";
        document.querySelector("body").appendChild(newDiv);
    }
}

document.querySelector("#btn").addEventListener("click", switchDiv);
#divId {
    background: red;
    height: 100px;
    width: 100px;
    position: relative;
    
}
<body>
  <button id="btn">Let's Diiiv!</button>
</body>



0

PHP 매뉴얼 :

isset — 변수가 설정되어 있고 NULL이 아닌지 확인

그리고 이런 식으로 인터페이스하십시오 :

bool isset ( mixed $var [, mixed $... ] )

매개 변수 $var는 확인할 변수입니다. 그러나 매개 변수의 수는 제한이 없습니다.

isset ()은 TRUEvar가 존재하고 이외의 값을 갖는 경우를 반환 합니다 NULL. FALSE그렇지 않으면.

몇 가지 예 :

$foo = 'bar';
var_dump(isset($foo));        -> true

$baz = null;
var_dump(isset($baz));        -> false

var_dump(isset($undefined));  -> false

이것을 염두에두고, 분명히 PHP isset()기능 과 똑같은 것을 쓸 수는 없습니다 . 예를 들어 다음과 같이 호출하면

if (isset(some_var)) {

}

function issset() {
    // function definition
}

자바 스크립트 트리거 Uncaught ReferenceError: some_var is not defined at (file_name):line_number . 이 동작에서 중요하고 주목할만한 점은 존재하지 않는 변수를 일반 함수에 전달하려고하면 오류가 발생한다는 것입니다.

그러나 PHP에서 isset() 에서는 실제로는 일반적인 함수가 아니라 언어 구조입니다. 즉, PHP 언어 자체의 일부이며 정상적인 함수 규칙을 따르지 않으므로 존재하지 않는 변수에 대한 오류를 유발하지 않아도됩니다. 변수가 존재하는지 여부를 알아낼 때 중요합니다. 그러나 javscript에서는 존재하지 않는 변수가있는 함수 호출과 같은 오류가 발생합니다.

내 요점은 우리가 그것을 동등한 javscript 함수로 쓸 수는 없지만 이런 식으로 할 수 있다는 것입니다

if (typeof some_var !== 'undefined') {
   // your code here
}

정확히 같은 효과를 원한다면 PHP도 확인하십시오. NULL

예를 들어

$baz = null;
var_dump(isset($baz));        -> false

그래서 우리는 이것을 자바 스크립트에 통합 할 수 있으며 다음과 같이 보입니다 :

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}

0

자바 스크립트 설정

let test = {
  a: {
    b: [0, 1]
  }
};

console.log(test.isset('a.b'))   // true
console.log(test.isset('a.b.1')) // true
console.log(test.isset('a.b.5')) // false
console.log(test.isset('a.c'))   // false
console.log('abv'.isset('0'))    // true

0

ES6 에서 주의하십시오 . let 변수 의 선언을 확인하고 선언하지 않으면 이전의 모든 솔루션이 작동 하지 않습니다.

let myTest = 'text';

if(typeof myTest === "undefined") {
    var myTest = 'new text'; // can't be a let because let declare in a scope
}

당신은 오류가 나타납니다

Uncaught SyntaxError : 식별자 'myTest'가 이미 선언되었습니다

해결책은 var로 변경하는 것이 었습니다.

var myTest = 'text'; // I replace let by a var

if(typeof myTest === "undefined") {
    var myTest = 'new text';
}

당신이 VAR하여하자를 변경할 수있는 경우에 다른 해결책, 당신은 제거 할 필요가 VAR을

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}

-1
    isset('user.permissions.saveProject', args);

    function isset(string, context) {
        try {
            var arr = string.split('.');
            var checkObj = context || window;

            for (var i in arr) {
                if (checkObj[arr[i]] === undefined) return false;
                checkObj = checkObj[arr[i]];
            }

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