Setara JavaScript isset ()

553

Di PHP bisa Anda lakukan if(isset($array['foo'])) { ... }. Dalam JavaScript Anda sering menggunakan if(array.foo) { ... }untuk melakukan hal yang sama, tetapi ini bukan pernyataan yang persis sama. Kondisi ini juga akan bernilai false jika array.fooada tetapi ada falseatau 0(dan mungkin juga nilai lainnya).

Apa yang setara dengan PHP issetdi JavaScript?

Dalam arti yang lebih luas, panduan umum dan lengkap tentang penanganan JavaScript atas variabel yang tidak ada, variabel tanpa nilai, dll. Akan lebih mudah.

Bart van Heukelom
sumber
1
Saya menulis sebuah fungsi yang akan menguji keberadaan properti objek tidak peduli kedalaman pertanyaan: stackoverflow.com/a/12681101/1268003 Menggunakan kode saya, dikombinasikan dengan beberapa pengetahuan yang dibagikan oleh @CMS di utas ini, Anda dapat dengan mudah menulis global fungsi yang bekerja sangat mirip dengan PHP: s isset.
Martin Andersson
3
Jika Anda menggunakan Underscore.js coba_.isUndefined(arr.foo)
Vitalii Fedorenko
Chaining Opsional mungkin adalah apa yang kebanyakan orang akan cari stackoverflow.com/a/60845999/2100372
zoran404

Jawaban:

938

Saya biasanya menggunakan typeofoperator:

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

Ini akan kembali "undefined"jika properti tidak ada atau nilainya undefined.

(Lihat juga: Perbedaan antara undefineddan tidak didefinisikan. )

Ada cara lain untuk mengetahui apakah properti ada pada objek, seperti hasOwnPropertymetode:

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

Dan inoperator:

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

Perbedaan antara dua yang terakhir adalah bahwa hasOwnPropertymetode akan memeriksa apakah properti ada secara fisik pada objek (properti tidak diwarisi).

The inOperator akan memeriksa semua properti dicapai dalam rantai prototipe, misalnya:

var obj = { foo: 'bar'};

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

Seperti yang Anda lihat, hasOwnPropertykembali falsedan inoperator kembali trueketika memeriksa toStringmetode, metode ini didefinisikan dalam rantai prototipe, karena objmewarisi bentuk Object.prototype.

CMS
sumber
23
Mengapa menggunakan typeofbukan if( obj.foo !== undefined )?
Matt Ball
7
Ah. Suatu hari saya akan menulis sepotong Javascript yang benar-benar lintas-browser. Sampai saat itu ...
Matt Ball
37
masalah dengan ini adalah Anda mendapatkan kesalahan ketika Anda mencoba untuk memeriksa properti yang lebih dalam, misalnya: obj.thisdoesntexist.foo! == tidak terdefinisi. Dalam PHP Anda dapat menggunakan isset atau mengosongkan dan dengan aman sedalam-dalamnya.
Enrique
6
IE8 tidak memiliki "hasOwnPropery"
max4ever
12
Tepatnya, PHP memungkinkan isset($abc->def->ghi->jkl)tanpa memunculkan pengecualian dan menghentikan skrip, tidak seperti typeofoperator JavaScript . Anda harus menggunakan sesuatu seperti try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy
43

Umur utas lama, tetapi ada cara baru untuk menjalankan yang setara isset().

ESNext (Tahap 4 Desember 2019)

Dua sintaks baru memungkinkan kami untuk sangat menyederhanakan penggunaan isset()fungsi:

Harap baca dokumen dan perhatikan kompatibilitas browser.

Jawaban Sebelumnya

Lihat penjelasan di bawah ini. Catatan saya menggunakan sintaks StandardJS

Contoh Penggunaan

// 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

Fungsi Jawab

/**
 * 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
  }
}

Penjelasan

PHP

Perhatikan bahwa dalam PHP Anda dapat mereferensikan variabel apa pun pada kedalaman apa pun - bahkan mencoba mengakses non-array sebagai array akan mengembalikan yang sederhana trueatau 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

Dalam JavaScript, kami tidak memiliki kebebasan itu, kami akan selalu mendapatkan kesalahan jika kami melakukan hal yang sama karena JS segera berusaha mengakses nilai deeper sebelum kami dapat membungkusnya dalam isset()fungsi kami jadi ...

// 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

Alternatif yang lebih banyak gagal:

// 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

Dan beberapa alternatif kerja yang bisa menjadi redundan dengan cepat:

// 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

Kesimpulan

Semua jawaban lain - meskipun sebagian besar layak ...

  1. Asumsikan Anda hanya memeriksa untuk melihat apakah variabel tidak terdefinisi baik untuk beberapa kasus penggunaan tetapi masih bisa melempar Kesalahan
  2. Anggap Anda hanya mencoba mengakses properti tingkat atas, yang lagi baik untuk beberapa kasus penggunaan
  3. Memaksa Anda untuk menggunakan pendekatan yang kurang ideal dibandingkan dengan PHP isset()
    misalnyaisset(some, 'nested.deeper.value')
  4. Gunakan eval()yang berfungsi tetapi saya pribadi hindari

Saya pikir saya sudah membahas banyak hal. Ada beberapa poin yang saya buat dalam jawaban saya yang tidak saya sentuh karena mereka - meskipun relevan - bukan bagian dari pertanyaan. Namun, jika perlu, saya dapat memperbarui jawaban saya dengan tautan ke beberapa aspek yang lebih teknis berdasarkan permintaan.

Saya menghabiskan banyak waktu untuk hal ini sehingga mudah-mudahan ini membantu orang keluar.

Terima kasih telah membaca!

Enom
sumber
25

Referensi ke SUMBER

    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 sebagian besar pensiun karena locutus. Berikut ini tautan baru http://locutus.io/php/var/isset

Ijas Ameenudeen
sumber
6
Ini akan memunculkan eksepsi ketika memanggil isset(abc.def.ghi)seandainya abc.deftidak terdefinisi. Namun dengan menggabungkan solusi ini dengan yang menerima nama variabel dalam bentuk string, itu akan identik dengan versi PHP.
Steven Pribilinskiy
17
if (!('foo' in obj)) {
  // not set.
}
kennytm
sumber
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;

 } 
//
//
pengesampingan publik
sumber
8

Solusi sederhana ini berfungsi, tetapi tidak untuk pemeriksaan objek dalam.

function isset(str) {
    return window[str] !== undefined;
}
Rodolfo Jorge Nemer Nogueira
sumber
6

Saya selalu menggunakan fungsi generik ini untuk mencegah kesalahan pada variabel primitif serta array dan objek.

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
Innovaat
sumber
5

Jika Anda menggunakan underscorejs, saya selalu menggunakan

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

Ini adalah solusi yang cukup anti peluru untuk pengujian jika ada variabel:

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

Sayangnya, Anda tidak bisa hanya merangkumnya dalam suatu fungsi.

Anda mungkin berpikir untuk melakukan sesuatu seperti ini:

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

Namun, ini akan menghasilkan kesalahan referensi jika variabel variablebelum didefinisikan, karena Anda tidak bisa meneruskan variabel yang tidak ada ke suatu fungsi:

ReferenceError Uncaught: foo tidak didefinisikan

Di sisi lain, ini memungkinkan Anda untuk menguji apakah parameter fungsi tidak terdefinisi:

var a = '5';

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

test(a);

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

Meskipun tidak ada nilai untuk yditeruskan ke fungsi test, issetfungsi kami berfungsi dengan baik dalam konteks ini, karena ydikenal dalam fungsi testsebagai undefinednilai.

John Slegers
sumber
Nit kecil: `? true: false` superflous. Hasilnya !==sudah boolean.
ToolmakerSteve
4
(typeof SOMETHING) !== 'undefined'

Terlalu panjang untuk menulis saat digunakan. Tetapi kami tidak dapat mengemas typeofkata kunci ke dalam suatu fungsi, karena kesalahan akan terjadi sebelum fungsi dipanggil, seperti ini:

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

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

Jadi saya menemukan cara:

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

isdef(typeof SOMETHING);

Ia dapat bekerja baik dengan variabel individual (variabel yang tidak ada sama sekali), atau properti objek (properti tidak ada). Dan hanya 7 karakter lebih banyak dari PHP isset.

LI XiangChen
sumber
Ini berfungsi untuk saya, menggunakannya untuk memeriksa apakah ada respons json tertentu.
Julius
3

Solusi ini berhasil untuk saya.

function isset(object){
    return (typeof object !=='undefined');
}
Bastien Viatge
sumber
5
Menjalankan isset(var)dengan vartidak disetel:ReferenceError: var is not defined
Gui Imamura
3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}
Filipe Sarturi
sumber
4
tambahkan beberapa deskripsi juga.
Shree Krishna
Seperti beberapa jawaban sebelumnya telah disebutkan, ini akan melempar ReferenceError jika dipanggil dengan variabel yang belum pernah dideklarasikan. Misalnya isset(someVar), di mana someVartidak pernah dinyatakan. Namun mengingat bahwa Anda lakukan eval, Anda mungkin berniat string yang akan disahkan dalam. Tampilkan penggunaan. Apakah tujuan penggunaan Anda isset('someVar')? Jika demikian, ini terlihat mirip dengan jawaban sebelumnya - bagaimana dengan jawaban Anda yang baru?
ToolmakerSteve
3
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; }
};

plus Tes:

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

Oleg Meshaev
sumber
Seperti beberapa jawaban sebelumnya telah disebutkan, ini akan melempar ReferenceError jika dipanggil dengan variabel yang belum pernah dideklarasikan.
ToolmakerSteve
3

Untuk memeriksa apakah blok html ada atau tidak, saya menggunakan kode ini:

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

Berikan path objek sebagai string, maka Anda dapat memecah string ini menjadi path dan menyelesaikan hasOwnPropertypada setiap langkah sambil menimpa objek itu sendiri dengan setiap iterasi.

Jika Anda mengkode dalam lingkungan ES6, lihat Ques stackoverflow ini .

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
);

Gajus
sumber
2

Saya menggunakan fungsi yang dapat memeriksa variabel dan objek. sangat nyaman untuk bekerja dengan jQuery

    function _isset (variable) {
        if(typeof(variable) == "undefined" || variable == null)
            return false;
        else
            if(typeof(variable) == "object" && !variable.length) 
                return false;
            else
                return true;
    };
Евгений Кичаев
sumber
Seperti beberapa jawaban sebelumnya telah disebutkan, ini akan melempar ReferenceError jika dipanggil dengan variabel yang belum pernah dideklarasikan.
ToolmakerSteve
1

Itu benar-benar masalah bagi saya ketika saya mengakses properti yang lebih dalam dari suatu objek jadi saya membuat fungsi yang akan mengembalikan nilai properti jika ada, jika tidak maka akan kembali salah. Anda dapat menggunakannya untuk menghemat waktu Anda,

//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
bikash.bilz
sumber
1

Jika Anda ingin memeriksa apakah suatu elemen ada, gunakan saja kode berikut:

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

Ini adalah contoh:

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>

Krzysztof AN
sumber
0
if (var) {
  // This is the most concise equivalent of Php's isset().
} 
doncadavona
sumber
0

Manual PHP mengatakan:

isset - Menentukan apakah variabel diatur dan bukan NULL

Dan antarmuka seperti ini:

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

Parameter $varadalah variabel yang akan diperiksa. itu dapat memiliki sejumlah parameter.

isset () mengembalikan TRUEjika var ada dan memiliki nilai selain NULL. FALSEjika tidak.

Beberapa contoh:

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

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

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

Karena ini dalam pikiran, Rupanya, itu tidak mungkin untuk menulis persis sama dengan isset()fungsi php . Misalnya ketika kita memanggil seperti ini:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Pemicu Javascript Uncaught ReferenceError: some_var is not defined at (file_name):line_number. Hal penting dan luar biasa tentang perilaku ini adalah bahwa ketika mencoba meneruskan variabel yang tidak ada ke fungsi normal, kesalahan dipicu.

Tetapi dalam PHP isset()sebenarnya bukan fungsi biasa tetapi konstruksi bahasa. Itu berarti mereka bagian dari bahasa PHP itu sendiri, tidak bermain dengan aturan fungsi normal dan karenanya bisa lolos dengan tidak memicu kesalahan untuk variabel yang tidak ada. Ini penting ketika mencoba mencari tahu apakah suatu variabel ada atau tidak. Tetapi dalam javascript, memicu kesalahan di tempat pertama mengatakan panggilan fungsi dengan variabel tidak ada.

Maksud saya adalah bahwa kita tidak dapat menulisnya sebagai fungsi javscript yang sama tetapi kita dapat melakukan sesuatu seperti ini

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

Jika Anda ingin efek yang sama persis PHP juga memeriksa varable tidak NULL

Sebagai contoh

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

Jadi, kita bisa memasukkan ini ke dalam javascript maka akan terlihat seperti ini:

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

penerbit javascript

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
Алексей Арх
sumber
0

Hati-hati dalam ES6 , semua solusi sebelumnya tidak berfungsi jika Anda ingin memeriksa deklarasi variabel let dan mendeklarasikannya, jika tidak

contoh

let myTest = 'text';

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

Anda akan melihat kesalahan

Uncaught SyntaxError: Identifier 'myTest' telah dinyatakan

Solusinya adalah mengubahnya dengan var

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

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

solusi lain jika Anda dapat mengubah let oleh var, Anda harus menghapus var Anda

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}
Laurent Chaloupe
sumber
-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;
        }
    }
Vano
sumber