JavaScript isset()等价

时间:2010-02-17 14:54:36

标签: javascript isset

在PHP中,您可以if(isset($array['foo'])) { ... }。在JavaScript中,您经常使用if(array.foo) { ... }来执行相同操作,但这不是完全相同的语句。如果array.foo确实存在但false0(以及可能还有其他值),则条件也会评估为假。

JavaScript中isset的完美等价是什么?

从更广泛的意义上讲,JavaScript处理不存在的变量,没有值的变量等的一般完整指南会很方便。

25 个答案:

答案 0 :(得分:859)

我通常使用typeof运算符:

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

如果该属性不存在或其值为"undefined",它将返回undefined

(另见:Difference between undefined and not being defined.

还有其他方法可以确定对象上是否存在属性,例如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运算符在检查true方法时返回toString,此方法在原型链,因为obj继承了Object.prototype形式。

答案 1 :(得分:23)

  

Reference to SOURCE

    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

答案 2 :(得分:23)

陈旧的线程,但这是运行等效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
 */
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
  }
}

解释

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

JS

在JavaScript中,我们没有那种自由,如果我们这样做,我们总会收到错误 因为JS立即尝试访问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

Object.hasOwnProperty('value', some.nested.deeper) // Error
//                                  ^^^^^^ undefined

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

一些可以快速实现冗余的可行替代方案:

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

结论

所有其他答案 - 尽管大多数都是可行的......

  1. 假设您只是检查变量是否未定义   对于某些用例很好,但仍然可以抛出错误
  2. 假设您只是尝试访问顶级属性,这也是   某些用例很好
  3. 强制您使用与PHP isset()相比不太理想的方法   例如isset(some, 'nested.deeper.value')
  4. 使用有效的eval(),但我个人避免
  5. 我想我已经涵盖了很多。我在答案中提出了一些观点 不要触及,因为它们 - 虽然相关 - 不属于 题。但是,如果需要,我可以通过链接更新我的答案 基于需求的更多技术方面。

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

    感谢您的阅读!

答案 3 :(得分:17)

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

答案 4 :(得分: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;

 } 
//
//

答案 5 :(得分:8)

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

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

答案 6 :(得分:5)

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

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

答案 7 :(得分:5)

如果您使用underscorejs我总是使用

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

答案 8 :(得分:4)

这个解决方案对我有用。

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

答案 9 :(得分: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

即使y的值没有传递给函数test,我们的isset函数也可以在此上下文中完美运行,因为函数{{1}中已知y }}作为test值。

答案 10 :(得分:4)

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

答案 11 :(得分: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; }
};

加上测试:

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

答案 12 :(得分:2)

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

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

答案 13 :(得分: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

答案 14 :(得分:2)

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

它既可以用于单个变量(根本不存在的变量),也可以用于对象属性(不存在的属性)。并且只有7个字符而不是PHP isset

答案 15 :(得分:2)

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

如果您在ES6环境中进行编码,请查看this stackoverflow Ques

&#13;
&#13;
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
);
&#13;
&#13;
&#13;

答案 16 :(得分:0)

PHP手册说:

  

isset - 确定变量是否设置且不是NULL

和这样的界面:

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

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

如果var存在且<{1}}以外的值,则

isset()返回TRUE。否则NULL

一些例子:

FALSE

考虑到这一点,显然,不可能编写完全等效的php $foo = 'bar'; var_dump(isset($foo)); -> true $baz = null; var_dump(isset($baz)); -> false var_dump(isset($undefined)); -> false 函数。 例如,当我们这样称呼时:

isset()

Javascript触发器if (isset(some_var)) { } function issset() { // function definition } 。 这种行为的重要和显着之处在于,当尝试将不存在的变量传递给普通函数时,会触发错误。

但是在PHP Uncaught ReferenceError: some_var is not defined at (file_name):line_number中实际上并不是常规函数,而是语言结构。这意味着它们是PHP语言本身的一部分,不遵循正常的函数规则,因此可以避免不为不存在的变量触发错误。在尝试确定变量是否存在时,这很重要。但是在javscript中,它首先触发了一个错误,即使用不存在的变量进行函数调用。

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

isset()

如果你想要完全相同的效果PHP也检查varable不是if (typeof some_var !== 'undefined') { // your code here }

例如

NULL

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

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

答案 17 :(得分:0)

当我访问对象的更深的属性时,这对我来说确实是一个问题,因此我创建了一个函数,该函数将返回该属性值(如果存在),否则将返回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

答案 18 :(得分:0)

如果要检查元素是否存在,只需使用以下代码:

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>

答案 19 :(得分:0)

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

答案 20 :(得分:0)

在ES6中要小心,如果要检查 let变量的声明并进行声明,则所有以前的解决方案均无效,否则

示例

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

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

您会看到一个错误

未捕获的SyntaxError:标识符'myTest'已被声明

解决方案是通过var更改它

let myTest = 'text';

if(typeof myTest === "undefined") {
    myTest = 'new text'; // I remove the var declaration
}

另一种解决方案,如果您可以更改var的租约,则需要删除 var

invoke-command -ComputerName Server {Get-ItemProperty -Path 'C:\\windows'-Filter *.txt  } |  sort-object lastwritetime | FT

invoke-command -ComputerName Server {Get-ItemProperty -Path 'C:\\windows'-exclude *.log  } |  sort-object lastwritetime | FT

答案 21 :(得分:0)

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

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

答案 22 :(得分:-1)

if (var) {
  // This is the most concise equivalent of Php's isset().
} 

答案 23 :(得分:-1)

我使用了可以检查变量和对象的函数。使用jQuery非常方便

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

答案 24 :(得分:-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;
        }
    }