JavaScript isset()と同等


553

PHPでできますif(isset($array['foo'])) { ... }。JavaScript if(array.foo) { ... }では同じことをするためによく使用しますが、これはまったく同じステートメントではありません。条件がarray.foo存在する場合でも条件はfalseと評価されますが、falseor 0(およびおそらく他の値も)です。

issetJavaScript でPHPに完全に相当するものは何ですか?

広い意味では、存在しない変数、値のない変数などのJavaScriptの処理に関する一般的で完全なガイドが便利です。


1
私は、オブジェクトのプロパティクエリの関係なく、深さの存在をテストする関数を書いた:stackoverflow.com/a/12681101/1268003をこのスレッドで@CMSで共有するいくつかの知識と組み合わせて自分のコードを、使用して、簡単にグローバルを書くことができますPHP:s issetのように機能する関数。
Martin Andersson、2012年

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
}

最後の2つの違いは、hasOwnPropertyメソッドがプロパティがオブジェクトに物理的に存在するかどうかをチェックすることです(プロパティは継承されません)。

inオペレータは、例えば、プロトタイプチェーン内のすべてのプロパティ到達までにチェックします:

var obj = { foo: 'bar'};

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

ご覧のとおり、メソッドをチェックすると、hasOwnProperty戻り値falsein演算子が戻ります。このメソッドは、formを継承しているため、プロトタイプチェーンで定義されています。truetoStringobjObject.prototype


23
なぜ使うtypeofのではなくif( obj.foo !== undefined )
マットボール

7
ああ。ある日、私は真にクロスブラウザのJavaScriptを書きます。それまで...
マットボール

37
これに関する問題は、たとえばobj.thisdoesntexist.foo!== undefinedのように、より深いプロパティをチェックしようとするとエラーが発生することです。PHPでは、どの深さでもissetまたはemptyを安全に使用できます。
エンリケ

6
IE8には「hasOwnPropery」がありません
max4ever

12
まさに、PHP isset($abc->def->ghi->jkl)はJavaScriptのtypeofオペレーターとは異なり、例外を発生させたりスクリプトを停止したりすることなく許可します。次のようなものを使用する必要があります try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy

43

古いスレッドですが、同等のものを実行する新しい方法がありますisset()

ESNext(2019年12月4日ステージ)

2つの新しい構文により、isset()機能の使用を大幅に簡略化できます。

ドキュメントを読み、ブラウザの互換性に注意してください。

前の回答

説明については、以下を参照してください。Note私は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では、任意の深さで任意の変数を参照できることに注意してください。配列が単純なtrueor を返すため、非配列にアクセスしようとしても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 ラップする前にJSが値にアクセスしようとするため、同じようにすると常にエラーが発生します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. PHPのisset()
    例に比べて理想的ではないアプローチを使用するように強制するisset(some, 'nested.deeper.value')
  4. eval()機能するが個人的には使用しない

たくさんカバーしたと思います。私の回答には、触れても触れないいくつかのポイントがあります。それらは、関連はありますが、質問の一部ではないためです。ただし、必要に応じて、需要に基づいて、より技術的な側面へのリンクで回答を更新できます。

私はこれに多くの時間を費やしたので、うまくいけばそれが人々の助けになるでしょう。

読んでくれてありがとう!


25

SOURCEへの参照

    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


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

私は常にこのジェネリック関数を使用して、プリミティブ変数、配列、オブジェクトのエラーを防ぎます。

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がfunction testに渡されない場合でも、関数は値として知られているissetため、この関数はこのコンテキストで完全yに機能testundefinedます。


マイナーニット: `?true:false`は不要です。の結果!==はすでにブール値です。
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クエリをご覧ください

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()はTRUE、varが存在し、以外の値を持つ場合に戻りますNULLFALSEさもないと。

いくつかの例:

$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
}

JavaScriptトリガーUncaught ReferenceError: some_var is not defined at (file_name):line_number。この動作の重要で注目すべき点は、存在しない変数を通常の関数に渡そうとすると、エラーが発生することです。

しかし、PHP isset()では実際には通常の関数ではなく、言語の構成要素です。つまり、それらはPHP言語自体の一部であり、通常の関数の規則に従っていないため、存在しない変数のエラーをトリガーしないことで回避できます。これは、変数が存在するかどうかを把握しようとするときに重要です。しかし、javscriptでは、そもそも存在しない変数を使用したsay関数呼び出しでエラーが発生します。

私の要点は、それを同等のjavscript関数として書くことはできないが、次のようなことはできるということです。

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

PHPとまったく同じ効果が必要な場合は、変数もチェックしてください NULL

例えば

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

これをJavaScriptに組み込むと、次のようになります。

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

0

javascript isset

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
}

エラーが表示されます

キャッチされていないSyntaxError:識別子 'myTest'はすでに宣言されています

解決策はそれを変数で変更することでした

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

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

あなたはvarでLETを変更することができれば、別の解決策は、あなたが削除する必要が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.