618

在 PHP 中你可以做到if(isset($array['foo'])) { ... }。在 JavaScript 中你经常使用if(array.foo) { ... }做同样的事情,但这不是完全一样的陈述。array.foo如果确实存在但为false0(可能还有其他值),该条件也将评估为假。

什么是issetJavaScript 中 PHP 的完美等价物?

在更广泛的意义上,关于 JavaScript 处理不存在的变量、没有值的变量等的通用、完整指南会很方便。


更新:11 年零 11 个月前我发布了这个问题,哇,它仍然有很多活动。现在,我很确定当我写这篇文章时,我只想知道如何检查关联数组(又名字典)中是否存在属性,因此正确的(对我而言)答案涉及hasOwnPropertyin运算符. 我对检查局部或全局变量不感兴趣。

但是,虽然我记得很清楚,但这个意图在所写的问题中并不十分清楚,甚至直接与之相矛盾!我从来没有提到过关联数组,而 PHPisset也可以做其他事情。让这成为我们所有人的一课,了解在问题中正确陈述您的要求是多么重要,以及全局变量、局部变量、对象属性、字典键和你不是 Huey、Dewey、和路易。

与此同时(呵呵),很多人也提供了这个效果的答案,所以对于那些通过谷歌找到这个问题的人来说,我很高兴我的模糊性在某种程度上有所帮助。无论如何,只是想澄清一下。

4

28 回答 28

1040

我一般使用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
}

后两者的区别在于该hasOwnProperty方法将检查该属性是否物理地存在于对象上(该属性不被继承)。

操作员将in检查原型链中所有可达的属性,例如:

var obj = { foo: 'bar'};

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

如您所见,在检查方法时hasOwnProperty返回falsein操作符返回,该方法是在原型链中定义的,因为继承了 form 。truetoStringobjObject.prototype

于 2010-02-17T14:57:51.550 回答
73

旧线程,但有新方法可以运行等效的isset().

ESNext(2019 年 12 月 4 日)

两种新语法使我们能够极大地简化isset()功能的使用:

请阅读文档并注意浏览器的兼容性。

回答

请参阅下面的说明。注意我使用 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
 * @returns {Boolean}           Value is not undefined or null
 */
function isset (accessor) {
  try {
    // Note we're seeing if the returned value of our function is not
    // undefined or null
    return accessor() !== undefined && accessor() !== null
  } catch (e) {
    // And we're able to catch the Error it would normally throw for
    // referencing a property of undefined
    return false
  }
}

NPM 包

这个答案功能isset-php在 NPM 上作为包提供。该包包含一些改进,例如类型检查和支持多个参数。

npm install --save isset-php

自述文件中提供了完整的文档。

const isset = require('isset-php')
let val = ''

// This will evaluate to true so the text will be printed.
if (isset(() => val)) {
  console.log('This val is set so I will print.')
}

解释

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

JavaScript

在 JavaScript 中,我们没有那种自由;如果我们做同样的事情,我们总是会得到一个错误,因为引擎会deeper在我们将它包装到我们的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

// Similar to the above but safe from objects overriding `hasOwnProperty`
Object.prototype.hasOwnProperty.call(some.nested.deeper, 'value') // Error
//                                        ^^^^^^ undefined

// Same goes for typeof
typeof some.nested.deeper !== 'undefined' // Error
//          ^^^^^^ undefined

还有一些可以快速获得冗余的可行替代方案:

// Wrap everything in try...catch
try {
  if (isset(some.nested.deeper)) {
    // ...
  }
} catch (e) {}

try {
  if (some.nested.deeper !== undefined && some.nested.deeper !== null) {
    // ...
  }
} 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()哪个有效,但我个人避免

我想我涵盖了很多。我在回答中提出了一些我没有涉及的观点,因为它们 - 尽管相关 - 不是问题的一部分(例如短路)。不过,如果需要,我可以根据需求使用指向一些更技术方面的链接来更新我的答案。

我花了很多时间在这上面,所以希望它可以帮助人们。

感谢您的阅读!

于 2017-09-16T18:08:31.277 回答
25

参考来源

    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

于 2012-11-20T01:48:20.137 回答
21
if (!('foo' in obj)) {
  // not set.
}
于 2010-02-17T14:59:43.120 回答
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;

 } 
//
//
于 2013-08-21T13:23:17.967 回答
8

这个简单的解决方案有效,但不适用于深度对象检查。

function isset(str) {
    return window[str] !== undefined;
}
于 2014-06-21T16:33:58.517 回答
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
于 2015-08-07T14:04:33.503 回答
5

这个解决方案对我有用。

function isset(object){
    return (typeof object !=='undefined');
}
于 2015-05-18T13:18:26.483 回答
5

如果你使用underscorejs我总是使用

if (!_.isUndefined(data) && !_.isNull(data)) {
     //your stuff
}
于 2016-02-19T11:23:05.100 回答
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

即使没有值 fory传递给 function test,我们的isset函数在这种情况下也能完美运行,因为y在函数中被称为testundefined

于 2016-02-19T11:49:07.960 回答
4
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

于 2016-12-08T01:31:42.077 回答
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

于 2017-11-02T13:12:17.360 回答
3
function isset(variable) {
    try {
        return typeof eval(variable) !== 'undefined';
    } catch (err) {
        return false;
    }
}
于 2016-03-08T04:05:47.487 回答
3

要检查 html 块是否存在,我正在使用以下代码:

if (typeof($('selector').html()) != 'undefined') {
    // $('selector') is existing
    // your code here
}
于 2017-06-06T07:53:12.483 回答
2

将对象路径作为字符串提供,然后您可以将此字符串分解为路径并hasOwnProperty在每一步解析,同时在每次迭代时覆盖对象本身。

如果您在 ES6 环境中编码,请查看此 stackoverflow 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
);

于 2014-11-18T08:29:16.613 回答
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;
    };
于 2019-05-28T12:30:00.943 回答
2

尝试在 Javascript 中创建类似于 PHP 的空函数的函数。愿这有帮助。

function empty(str){
  try{
    if(typeof str==="string"){
        str=str.trim();
    }
    return !(str !== undefined && str !== "undefined" && str !== null && str!=="" && str!==0 && str!==false);
  }catch(ex){
    return true;
  }
 }

console.log(empty(0))//true
console.log(empty(null))//true
console.log(empty(" "))//true
console.log(empty(""))//true
console.log(empty(undefined))//true
console.log(empty("undefined"))//true

var tmp=1;
console.log(empty(tmp))//false

var tmp="Test";
console.log(empty(tmp))//false

var tmp=" Test ";
console.log(empty(tmp))//false

var tmp={a:1,b:false,c:0};
console.log(empty(tmp.a))//false
console.log(empty(tmp.b))//true
console.log(empty(tmp.c))//true
console.log(empty(tmp.c))//true
console.log(empty(tmp.c.d))//true
于 2020-07-29T03:31:39.620 回答
1

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

考虑到这一点,显然,不可能编写完全等效的 phpisset()函数。例如当我们这样调用时:

if (isset(some_var)) {

}

function issset() {
    // function definition
}

Javascript 触发器Uncaught ReferenceError: some_var is not defined at (file_name):line_number。这种行为的重要和显着之处在于,当尝试将不存在的变量传递给正常函数时,会触发错误。

但在 PHPisset()中实际上不是常规函数,而是语言结构。这意味着它们是 PHP 语言本身的一部分,不遵守函数的正常规则,因此可以避免不触发不存在变量的错误。这在试图确定变量是否存在时很重要。但是在 javscript 中,它首先会触发一个错误,比如使用不存在的变量调用函数。

我的观点是我们不能把它写成等效的 javscript 函数,但我们可以做这样的事情

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

如果你想要完全相同的效果 PHP 也检查 varable is notNULL

例如

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

因此,我们可以将其合并到 javascript 中,然后它看起来像这样:

if (typeof some_var !== 'undefined' && some_var !== null) {
   // your code here
}
于 2017-10-26T04:17:59.203 回答
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
于 2019-07-04T11:53:10.700 回答
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>

于 2019-07-20T11:54:34.477 回答
1

最后我用简单的解决方案解决了问题:

if (obj && obj.foo && obj.foo='somethings'){
console.log('i,m work without error')
}
于 2021-05-26T05:44:15.890 回答
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 更改它

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
}
于 2020-05-07T15:53:50.283 回答
0

https://jsfiddle.net/31b6mhtj/

arr={nested:{nested2:{val:'isset'}}}
if(t=isset(arr,'nested=>nested2=>val')){
alert(t)
}
function isset(obj,nested) {
    var dub=obj
    var isset=false
    if(typeof(obj)!="undefined" && typeof(nested)!="undefined"){
        var arr=nested.split('=>');
        for(var k in arr){
            var key=arr[k];
            if(typeof(dub[key])=="undefined"){
                isset=false;
                break;
            }
            dub=dub[key];
      isset=dub
        }   
    }
    
    return isset;
}
于 2021-08-13T12:34:06.750 回答
-1

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
于 2019-10-22T09:08:17.793 回答
-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;
        }
    }
于 2019-11-06T14:42:57.580 回答
-1
try {
  const value = array.foo.object.value;
  // isset true
} catch (err) {
  // isset false
}
于 2022-01-27T15:34:18.130 回答
-2
if (var) {
  // This is the most concise equivalent of Php's isset().
} 
于 2017-08-14T15:48:14.450 回答
-2

这是最简洁的 Php 等价物isset()

if(var == undefined)
  • true 这是 var!isset
  • false这是 varisset
于 2022-02-08T16:31:45.830 回答