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

JavaScript中与PHP的isset完美对应的是什么?

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


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

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

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


我通常使用typeof操作符:

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

如果属性不存在或其值未定义,则返回“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

如你所见,在检查toString方法时,hasOwnProperty返回false, in操作符返回true,这个方法是在原型链中定义的,因为obj继承了Object.prototype的形式。


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

参考资料来源

    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

如果你用下划线,我总是用

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的值没有传递给函数测试,我们的isset函数在这个上下文中工作得很好,因为y在函数测试中是一个未定义的值。


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()函数的使用:

可选的链接(?)。 空合并运算符(??)

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

回答

请看下面的解释。注意我使用的是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的地方

这个回答函数可以在NPM上的isset-php包中找到。这个包包含了一些改进,比如类型检查和支持多参数。

npm install --save isset-php

完整的文档可以在README中找到。

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中,您可以在任何深度引用任何变量——甚至可以尝试引用 将非数组作为数组访问将返回一个简单的true或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中,我们没有这样的自由;如果这样做,总是会得到一个错误 同样,因为引擎会立即尝试访问更深的值,然后我们才能将其包装在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

结论

所有其他的答案——尽管大多数是可行的……

假设你只是在检查变量是否未定义 对于一些用例是好的,但仍然可以抛出一个错误 假设您只是试图访问顶级属性,同样是 对于某些用例来说很好 强制您使用相对于PHP的isset()不太理想的方法 例如isset(some, 'nested.deep .value') 使用eval(),这是有效的,但我个人避免使用

我想我已经讲过很多了。我在回答中提出了一些观点 不要触及,因为他们-虽然相关-不是的一部分 问题(如。短路)。如果需要,我可以更新我的答案与一些链接 基于需求的更多技术方面。

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

感谢您的阅读!


PHP手册说:

isset -确定一个变量是否已设置且不为NULL

界面是这样的:

混合$var[,混合$…])

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

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

一些例子:

$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变量的声明并声明它,那么之前的所有解决方案都是无效的

例子

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,你需要删除你的变量

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 !isset 这是var isset