1

変数/オブジェクトが設定されているかどうかを返す関数があります。

function isset() {
    var a = arguments, l = a.length;
    if (l === 0) { console.log("Error: isset() is empty"); }
    for (var i=0; i<l; i++) {
        try {
            if (typeof a[i] === "object") {
                var j=0;
                for (var obj in a[i]) { j++; }
                if (j>0) { return true; }
                else { return false; }
            }
            else if (a[i] === undefined || a[i] === null) { return false; }
        }
        catch(e) {
            if (e.name === "ReferenceError") { return false; }
        }
    }
    return true;
}

たとえば、これは機能します:

var foo;
isset(foo);        // Returns false
foo = "bar";
isset(foo);        // Returns true
foo = {};
isset(foo);        // Returns false
isset(foo.bar);    // Returns false
foo = { bar: "test" };
isset(foo);        // Returns true
isset(foo.bar);    // Returns true

ここに問題があります... foo が最初から設定されていない場合、これが起こります:

// foo has not been defined yet
isset(foo); // Returns "ReferenceError: foo is not defined"

error.name === "ReferenceError" の場合、try/catch/finally を使用して false を返すことができると思いましたが、機能していません。どこが間違っていますか?


編集:

したがって、以下の答えは正しいです。予想通り、未定義の変数にアクセスしたり、try/catch/finally でトラップしたりすることはできません (説明については以下を参照してください)。

ただし、これはあまりエレガントではない解決策です。変数の名前を引用符で囲んで渡し、eval を使用してチェックを行う必要があります。それは醜いですが、うまくいきます:

// Usage: isset("foo"); // Returns true or false
function isset(a) {
    if (a) {
        if (eval("!!window."+a)) {
            if (eval("typeof "+a+" === 'object'")) { return eval("Object.keys("+a+").length > 0") ? true : false; }
            return (eval(a+" === undefined") || eval(a+" === null") || eval(a+" === ''")) ? false : true;
        }
        else { return false; }
    }
    else { console.log("Empty value: isset()"); }
}

さらにフォローアップするために、一番上の元の関数をクリーンアップしました。変数が存在しない場合に ReferenceError が発生するという同じ問題がまだありますが、このバージョンの方がはるかにクリーンです。

// Usage: isset(foo); // Returns true or false if the variable exists.
function isset(a) {
    if (a) {
        if (typeof a === "object") { return Object.keys(a).length > 0 ? true : false; }
        return (a === undefined || a === null || a === "") ? false : true;
    }
    else { console.log("Empty value: isset()"); }
}
4

2 に答える 2