web-dev-qa-db-ja.com

JavaScriptのisset()に相当

PHPではif(isset($array['foo'])) { ... }を実行できます。 JavaScriptでは、if(array.foo) { ... }を使って同じことをすることがよくありますが、これはまったく同じ文ではありません。 array.fooが存在するがfalseまたは0(およびおそらく他の値も)の場合、条件はfalseと評価されます。

JavaScriptにおけるPHPのissetと完全に同等なものは何ですか?

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

499

私は一般的に 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メソッドがオブジェクト上にプロパティが存在するかどうかをチェックするということです( physical )(プロパティは継承されません)。

in演算子は、プロトタイプチェーンで到達可能なすべてのプロパティをチェックします。

var obj = { foo: 'bar'};

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

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

851
CMS

古いスレッドですが、これは同等の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では、任意の変数を任意の深さで参照できます。配列として非配列にアクセスしようとしても、単純な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がisset()関数でラップできるようになる前に、JSがすぐにdeeperの値にアクセスしようとしているので、同じようにしても常にエラーになります。

// 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. 変数が未定義ではないかどうかを確認するためだけにチェックしているとします。これはいくつかのユースケースでは問題ありませんが、それでもErrorをスローする可能性があります。
  2. トップレベルのプロパティにアクセスしようとしているだけであるとします。これも一部のユースケースでは問題ありません。
  3. PHPのisset()に対して、理想的ではないアプローチを使用するよう強制してください。
    例えば。 isset(some, 'nested.deeper.value')
  4. うまくいくeval()を使うが、私は個人的には避けている

私はそれをたくさんカバーしたと思います。私は自分の答えにいくつか指摘しておきたいことがありますが、それらは関係ありますが質問の一部ではないからです。必要であれば、しかし、私は私の答えを需要に基づくより技術的な側面のいくつかへのリンクで更新することができます。

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

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

23
Enom

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

23
Ijas Ameenudeen
if (!('foo' in obj)) {
  // not set.
}
17
kennytm

この単純な解決策は機能しますが、詳細なオブジェクトチェックには役立ちません。

function isset(str) {
    return window[str] !== undefined;
}
//
//  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;

 } 
//
//
8
public override

私はいつもこの汎用関数を使用して、配列やオブジェクトと同様にプリミティブ変数のエラーを防ぎます。

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
Innovaat

underscorejsを使用している場合 私は常に使用します

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

この解決策は私のために働いた。

function isset(object){
    return (typeof object !=='undefined');
}
4
Bastien Viatge
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}
4
Filipe Sarturi

これは、変数が存在するかどうかをテストするための非常に優れた解決策です。

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の値としてtestとして知られているので、このコンテキストではundefined関数は完全に機能します。

4
John Slegers
window.isset = function(v_var) {
    if(typeof(v_var) == 'number'){ if(isNaN(v_var)){ return false; }}
    if(typeof(v_var) == 'undefined' || v_var === null){ return false;   } else { return true; }
};

プラステスト

https://Gist.github.com/daylik/24acc318b6abdcdd63b46607513ae073

3
Oleg Meshaev

HTMLブロックが存在するかどうかを確認するために、私はこのコードを使用しています:

if (typeof($('selector').html()) != 'undefined') {
    // $('selector') is existing
    // your code here
}
2
Vito Gravano
(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 issetよりも7文字多いだけです。

2
LI XiangChen

オブジェクトパスを文字列として指定すると、この文字列をパスに分割し、各反復でオブジェクト自体を上書きしながら各ステップでhasOwnPropertyを解決できます。

ES6環境でコーディングしている場合は、 このスタックオーバーフロー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
Gajus

変数とオブジェクトをチェックできる関数を使用します。 jQueryを使用すると非常に便利

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

オブジェクトのより深いプロパティにアクセスしていたとき、それは本当に問題でした。そのため、存在する場合はプロパティ値を返す関数を作成し、そうでなければ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
bikash.bilz

要素が存在するかどうかを確認する場合は、次のコードを使用します。

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>
1
Krzysztof AN
if (var) {
  // This is the most concise equivalent of Php's isset().
} 
1
doncadavona

PHPマニュアルは言う:

isset - 変数が設定されていてNULLではないかどうかを判別

そして、このようなインターフェース

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

パラメータ$varは、チェック対象の変数です。ただし、パラメータはいくつでも指定できます。

varが存在し、TRUE以外の値を持つ場合、isset()は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
}

JavascriptがUncaught ReferenceError: some_var is not defined at (file_name):line_numberを起動します。この振る舞いに関する重要で注目すべきことは、存在しない変数を通常の関数に渡そうとするとエラーが引き起こされることです。

しかしPHP isset()は実際には通常の関数ではなく言語の構成要素です。つまり、それらはPHP言語自体の一部であり、通常の関数の規則に従っていないため、存在しない変数に対してエラーを引き起こさないことで回避できることを意味します。これは、変数が存在するかどうかを判断するときに重要です。しかしJavaScriptでは、そもそも存在しない変数による関数呼び出しなどのエラーを引き起こします。

私の言いたいことは、それを同等の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
Arjun Kariyadan