Tương đương JavaScript ()


553

Trong PHP bạn có thể làm if(isset($array['foo'])) { ... }. Trong JavaScript, bạn thường sử dụng if(array.foo) { ... }để làm tương tự, nhưng đây không hoàn toàn là cùng một tuyên bố. Điều kiện cũng sẽ đánh giá thành sai nếu array.footồn tại nhưng là falsehoặc 0(và có lẽ các giá trị khác nữa).

Tương đương hoàn hảo của PHP issettrong JavaScript là gì?

Theo nghĩa rộng hơn, một hướng dẫn chung, đầy đủ về cách xử lý các biến không tồn tại của JavaScript, các biến không có giá trị, v.v. sẽ thuận tiện.


1
Tôi đã viết một hàm sẽ kiểm tra sự tồn tại của một thuộc tính đối tượng bất kể độ sâu của truy vấn: stackoverflow.com/a/12681101/1268003 Sử dụng mã của tôi, kết hợp với một số kiến ​​thức được chia sẻ bởi @CMS trong luồng này, bạn có thể dễ dàng viết toàn cầu Hàm hoạt động rất giống PHP: s.
Martin Andersson

3
Nếu bạn sử dụng Underscore.js hãy thử_.isUndefined(arr.foo)
Vitalii Fedorenko

Chuỗi tùy chọn có lẽ là điều mà hầu hết mọi người sẽ tìm kiếm stackoverflow.com/a/60845999/2100372
zoran404

Câu trả lời:


938

Tôi thường sử dụng typeoftoán tử:

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

Nó sẽ trả lại "undefined"nếu tài sản không tồn tại hoặc giá trị của nó là undefined.

(Xem thêm: Sự khác biệt giữa undefinedvà không được xác định. )

Có nhiều cách khác để tìm hiểu xem một thuộc tính có tồn tại trên một đối tượng hay không, như hasOwnPropertyphương thức:

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

innhà điều hành:

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

Sự khác biệt giữa hai cái cuối cùng là hasOwnPropertyphương thức sẽ kiểm tra xem thuộc tính có tồn tại vật lý trên đối tượng không (thuộc tính không được thừa kế).

Các innhà điều hành sẽ kiểm tra trên tất cả các thuộc tính có thể truy cập lên trong chuỗi ban đầu, ví dụ:

var obj = { foo: 'bar'};

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

Như bạn có thể thấy, hasOwnPropertytrả về falseintoán tử trả về truekhi kiểm tra toStringphương thức, phương thức này được xác định trong chuỗi nguyên mẫu, vì objkế thừa biểu mẫu Object.prototype.


23
Tại sao sử dụng typeofchứ không phải if( obj.foo !== undefined )?
Matt Ball

7
Ah. Một ngày nào đó tôi sẽ viết một đoạn Javascript thực sự đa trình duyệt. Cho đến lúc đó ...
Matt Ball

37
vấn đề với điều này là bạn gặp lỗi khi bạn cố kiểm tra các thuộc tính sâu hơn, ví dụ: obj.thonomoesntexist.foo! == không xác định. Trong PHP bạn có thể sử dụng ngay lập tức hoặc trống và an toàn ở bất kỳ độ sâu nào.
Enrique

6
IE8 không có "hasOwnPropery"
max4ever

12
Chính xác, PHP cho phép isset($abc->def->ghi->jkl)mà không đưa ra một ngoại lệ và tạm dừng tập lệnh, không giống như typeoftoán tử của JavaScript . Bạn phải sử dụng một cái gì đó như try{ abc.def.ghi.jkl; isset=true } catch(e){ isset=false }
Steven Pribilinskiy

43

Tuổi cũ chủ đề, nhưng có những cách mới để chạy một tương đương isset().

ESNext (Giai đoạn 4 tháng 12 năm 2019)

Hai cú pháp mới cho phép chúng tôi đơn giản hóa rất nhiều việc sử dụng isset()chức năng:

Xin vui lòng đọc các tài liệu và quan tâm đến khả năng tương thích trình duyệt.

Trả lời trước

Xem bên dưới để giải thích. Lưu ý tôi sử dụng cú pháp StandardJS

Cách sử dụng ví dụ

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

Chức năng trả lời

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

Giải trình

PHP

Lưu ý rằng trong PHP bạn có thể tham chiếu bất kỳ biến nào ở bất kỳ độ sâu nào - thậm chí cố gắng truy cập vào một mảng không phải là một mảng sẽ trả về một đơn giản truehoặc 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

Mã não

Trong JavaScript, chúng tôi không có quyền tự do đó, chúng tôi sẽ luôn gặp lỗi nếu chúng tôi làm điều tương tự vì JS ngay lập tức cố gắng truy cập giá trị deeper trước khi chúng tôi có thể bọc nó trong isset()chức năng của mình để ...

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

Nhiều lựa chọn thay thế thất bại:

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

Và một số lựa chọn thay thế có thể nhận được dự phòng nhanh chóng:

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

Phần kết luận

Tất cả các câu trả lời khác - mặc dù hầu hết đều khả thi ...

  1. Giả sử bạn chỉ kiểm tra xem biến đó không được xác định, điều này tốt cho một số trường hợp sử dụng nhưng vẫn có thể gây ra Lỗi
  2. Giả sử bạn chỉ đang cố gắng truy cập vào một thuộc tính cấp cao nhất, một lần nữa sẽ tốt cho một số trường hợp sử dụng
  3. Buộc bạn sử dụng một cách tiếp cận ít lý tưởng hơn so với PHP, isset()
    vdisset(some, 'nested.deeper.value')
  4. Sử dụng eval()mà hoạt động nhưng cá nhân tôi tránh

Tôi nghĩ rằng tôi bao gồm rất nhiều nó. Có một số điểm tôi đưa ra trong câu trả lời của mình mà tôi không đề cập đến vì chúng - mặc dù có liên quan - không phải là một phần của câu hỏi. Tuy nhiên, nếu cần, tôi có thể cập nhật câu trả lời của mình bằng các liên kết đến một số khía cạnh kỹ thuật hơn dựa trên nhu cầu.

Tôi đã dành nhiều thời gian cho việc này vì vậy hy vọng nó sẽ giúp được mọi người.

Cảm ơn bạn đã đọc!


25

Tham chiếu đến NGUỒN

    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 hầu hết đã nghỉ hưu để ủng hộ locutus Đây là liên kết mới http://locutus.io/php/var/isset


6
Điều này sẽ đưa ra một ngoại lệ khi gọi isset(abc.def.ghi)trong trường hợp nếu abc.defkhông xác định. Tuy nhiên, bằng cách kết hợp giải pháp này với giải pháp chấp nhận tên biến dưới dạng chuỗi, nó sẽ giống hệt với phiên bản 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;

 } 
//
//

8

Giải pháp đơn giản này hoạt động, nhưng không phải để kiểm tra đối tượng sâu.

function isset(str) {
    return window[str] !== undefined;
}

6

Tôi luôn sử dụng hàm chung này để ngăn ngừa các lỗi trên các biến nguyên thủy cũng như các mảng và đối tượng.

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


4

Đây là một giải pháp chống đạn khá tốt để thử nghiệm nếu một biến tồn tại:

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

Thật không may, bạn không thể đơn giản gói gọn nó trong một hàm.

Bạn có thể nghĩ làm một cái gì đó như thế này:

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

Tuy nhiên, điều này sẽ tạo ra một lỗi tham chiếu nếu biến variablechưa được xác định, bởi vì bạn không thể chuyển dọc theo một biến không tồn tại cho một hàm:

Uncaught ReferenceError: foo không được xác định

Mặt khác, nó cho phép bạn kiểm tra xem các tham số chức năng không được xác định:

var a = '5';

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

test(a);

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

Mặc dù không có giá trị nào yđược truyền cho hàm test, issethàm của chúng ta hoạt động hoàn hảo trong ngữ cảnh này, vì yđược biết đến trong hàm testlà một undefinedgiá trị.


Tiểu nit: `? đúng: sai` là thừa. Kết quả !==đã là một boolean.
ToolmakerSteve

4
(typeof SOMETHING) !== 'undefined'

Nó quá dài để viết khi sử dụng. Nhưng chúng ta không thể gói typeoftừ khóa vào một hàm, vì một lỗi sẽ xuất hiện trước khi hàm được gọi, như thế này:

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

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

Vì vậy, tôi đã tìm ra một cách:

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

isdef(typeof SOMETHING);

Nó có thể hoạt động cả với các biến riêng lẻ (các biến hoàn toàn không tồn tại) hoặc thuộc tính đối tượng (thuộc tính không tồn tại). Và chỉ có 7 ký tự hơn PHP isset.


Điều này làm việc cho tôi, sử dụng nó để kiểm tra nếu một phản ứng json cụ thể tồn tại.
Julius

3

Giải pháp này đã làm việc cho tôi.

function isset(object){
    return (typeof object !=='undefined');
}

5
Gọi isset(var)với varunset:ReferenceError: var is not defined
Gui Imamura

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

4
thêm một số mô tả quá.
Shree Krishna

Như một số câu trả lời trước đó đã đề cập, điều này sẽ ném ReferenceError nếu được gọi với một biến chưa bao giờ được khai báo. Ví dụ isset(someVar), nơi someVarchưa bao giờ được tuyên bố. Tuy nhiên, nếu bạn làm như vậy eval, bạn có thể dự định một chuỗi được truyền vào. Hiển thị việc sử dụng. Là mục đích sử dụng của bạn isset('someVar')? Nếu vậy, điều này có vẻ tương tự như câu trả lời trước đó - câu trả lời của bạn là gì mới?
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; }
};

bài kiểm tra cộng:

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


Như một số câu trả lời trước đó đã đề cập, điều này sẽ ném ReferenceError nếu được gọi với một biến chưa bao giờ được khai báo.
ToolmakerSteve

3

Để kiểm tra khối html có tồn tại hay không, tôi đang sử dụng mã này:

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

2

Cung cấp đường dẫn đối tượng dưới dạng một chuỗi, sau đó bạn có thể chia chuỗi này thành một đường dẫn và giải quyết hasOwnProperty tại mỗi bước trong khi ghi đè lên chính đối tượng đó với mỗi lần lặp.

Nếu bạn đang mã hóa trong môi trường ES6, hãy xem Ques stackoverflow này .

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

Tôi sử dụng một chức năng có thể kiểm tra các biến và đối tượng. rất thuận tiện để làm việc với jQuery

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

Như một số câu trả lời trước đó đã đề cập, điều này sẽ ném ReferenceError nếu được gọi với một biến chưa bao giờ được khai báo.
ToolmakerSteve

1

Nó thực sự là một vấn đề đối với tôi khi tôi đang truy cập vào một thuộc tính sâu hơn của một đối tượng vì vậy tôi đã tạo một hàm sẽ trả về giá trị thuộc tính nếu tồn tại nếu không nó sẽ trả về false. Bạn có thể sử dụng nó để tiết kiệm thời gian của bạn,

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

Nếu bạn muốn kiểm tra xem một phần tử có tồn tại hay không, chỉ cần sử dụng đoạn mã sau:

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

Đây là mẫu:

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

Hướng dẫn sử dụng PHP nói:

isset - Xác định nếu một biến được đặt và không phải là NULL

Và giao diện giống như thế này:

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

Tham số $varlà biến cần kiểm tra. Nó có thể có bất kỳ số lượng tham số mặc dù.

Trả về () trả về TRUEnếu var tồn tại và có giá trị khác NULL.FALSEnếu không thì.

Một số ví dụ:

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

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

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

Rõ ràng, không thể viết chính xác isset()chức năng php . Ví dụ khi chúng ta gọi như thế này:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Trình kích hoạt Javascript Uncaught ReferenceError: some_var is not defined at (file_name):line_number. Điều quan trọng và đáng chú ý về hành vi này là khi cố gắng chuyển các biến không tồn tại sang các hàm bình thường, một lỗi được kích hoạt.

Nhưng trong PHP isset() không thực sự là các hàm thông thường mà là các cấu trúc ngôn ngữ. Điều đó có nghĩa là chúng là một phần của ngôn ngữ PHP, không chơi theo các quy tắc thông thường của hàm và do đó có thể thoát khỏi việc không gây ra lỗi cho các biến không tồn tại. Điều này rất quan trọng khi cố gắng tìm hiểu xem một biến có tồn tại hay không. Nhưng trong javscript, nó gây ra lỗi ở vị trí đầu tiên nói hàm gọi với các biến không tồn tại.

Quan điểm của tôi là chúng ta không thể viết nó dưới dạng hàm javscript tương đương nhưng chúng ta có thể làm một cái gì đó như thế này

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

Nếu bạn muốn chính xác hiệu ứng tương tự PHP cũng kiểm tra varable không NULL

Ví dụ

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

Vì vậy, chúng ta có thể kết hợp điều này vào javascript sau đó nó trông như thế này:

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

0

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

0

Hãy cẩn thận trong ES6 , tất cả các giải pháp trước đó không hoạt động nếu bạn muốn kiểm tra khai báo biến let và khai báo nó, nếu không

thí dụ

let myTest = 'text';

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

bạn sẽ thấy một lỗi

Uncaught SyntaxError: Mã định danh 'myTest' đã được khai báo

Giải pháp là thay đổi nó bằng var

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

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

một giải pháp khác nếu bạn có thể thay đổi cho phép bởi một var, bạn cần xóa var của bạn

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;
        }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.