JavaScript的isset()等价

在PHP中,可以使用if(isset($array['foo'])) { ... }。在JavaScript中,你经常使用if(array.foo) { ... }来做同样的事情,但这不是完全相同的语句。如果array.foo确实存在,但为false0(也可能为其他值),则条件也将计算为false。

PHP的isset在JavaScript中的完美对等物是什么?

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


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

但是,虽然我记得很清楚,但在写的问题中,这种意图并不十分清楚,甚至与之直接矛盾!我从来没有提到关联数组,PHP的isset也做了那些其他的事情。让这成为我们所有人的一个教训,让我们知道在一个问题中正确地陈述你的要求是多么重要,以及全局变量、局部变量、对象属性、字典键和其他什么东西是多么重要。

与此同时,很多很多人也提供了这个问题的答案,所以对于那些通过谷歌找到这个问题的人来说,我很高兴我的含糊在某种程度上有所帮助。不管怎样,我只是想澄清一下。

1033852 次浏览

我通常使用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返回false,而in操作符在检查toString方法时返回true,这个方法是在原型链中定义的,因为obj继承了Object.prototype的形式。

if (!('foo' in obj)) {
// not set.
}

< a href = " http://locutus。io/php/var/isset/" rel="nofollow noreferrer">引用SOURCE . io/php/var/isset/" rel="nofollow noreferrer

    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大部分都被淘汰了,取而代之的是蝗虫 这是新的链接http://locutus.io/php/var/isset

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


}
//
//

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

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

提供对象路径作为字符串,然后您可以将该字符串分解为一个路径,并在每一步解析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
);

这个解决方案对我很有效。

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

我总是使用这个泛型函数来防止基本变量以及数组和对象上的错误。

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

如果你使用underscorejs,我总是使用

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

这是一个非常可靠的测试变量是否存在的解决方案:

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

不幸的是,您不能简单地将其封装在函数中。

你可能会这样想:

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

但是,如果变量variable还没有定义,这将产生一个引用错误,因为你不能将一个不存在的变量传递给函数:

未定义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值。

function isset(variable) {
try {
return typeof eval(variable) !== 'undefined';
} catch (err) {
return false;
}
}
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

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

if (typeof($('selector').html()) != 'undefined') {
// $('selector') is existing
// your code here
}
if (var) {
// This is the most concise equivalent of Php's isset().
}

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

ESNext(2019年12月第四阶段)

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

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

回答

请看下面的解释。# EYZ0

示例使用

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

这个应答函数可以作为NPM上的isset-php包使用。这个包包含了一些改进,比如类型检查和支持多参数。

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中,你可以在任何深度引用任何变量——甚至可以尝试引用 将非数组作为数组访问将返回简单的truefalse:

// 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()
    的不太理想的方法 李如# EYZ0 < / >
  4. 使用eval(),但我个人不使用
我想我已经讲了很多了。我在回答中提出了一些观点 不要触及,因为他们-虽然相关-不是的一部分 问题(如。# EYZ0)。如果需要,我可以更新我的答案与一些链接 更多基于需求的技术方面

我在这上面花了很多时间,所以希望它能帮助到大家。

感谢您的阅读!

PHP手册说:

收取 -确定一个变量是否被设置并且不是NULL

界面是这样的:

# EYZ0

参数$var是要检查的变量。它可以有任意数量的参数。

如果var存在并且值不是NULL, isset()返回TRUE。# EYZ2否则。

一些例子:

$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语言本身的一部分,不遵循函数的正常规则,因此可以避免对不存在的变量触发错误。在试图确定一个变量是否存在时,这很重要。但在javscript中,它首先会触发一个错误,比如函数调用不存在的变量。

我的观点是,我们不能把它写成等效的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
}
(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个字符。

我使用了一个可以检查变量和对象的函数。使用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

如果你想检查一个元素是否存在,只需使用下面的代码:

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>

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

在ES6中要小心,如果你想检查一个让变量的声明并声明它,所有前面的解决方案都不工作,如果它不是

例子

let myTest = 'text';


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

您将看到一个错误

标识符'myTest'已经声明

解决办法是用一个变量

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


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

另一个解决方案是,如果你可以通过变量改变let,你需要删除var

let myTest = 'text';


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

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

if (obj && obj.foo && obj.foo='somethings'){
console.log('i,m work without error')
}

将此函数用于数组或嵌套数组(但不适用于字符串)

if(isset(array,'key1=>key1')){alert('isset');}

https://jsfiddle.net/dazzafact/cgav6psr/

arr={nested:{nested2:{val:'isset'}}}
if(t=isset(arr,'nested=>nested2=>val','=>')){
alert(t)
}
function isset(obj,nested,split) {
var sep=split || '.';
var dub=obj
var isset=false
if(typeof(obj)!="undefined" && typeof(nested)!="undefined"){
var arr=nested.split(sep);
for(var k in arr){
var key=arr[k];
if(typeof(dub[key])=="undefined"){
isset=false;
break;
}
dub=dub[key];
isset=dub
}
}
    

return isset;
}
try {
const value = array.foo.object.value;
// isset true
} catch (err) {
// isset false
}

这是Php的isset()最简洁的等价代码:

if(var == undefined)
  • 这是var
  • 这是var