等同于JavaScript isset()

2020/09/24 07:01 · javascript ·  · 0评论

在PHP中可以做到if(isset($array['foo'])) { ... }在JavaScript中,您通常会使用if(array.foo) { ... }相同的方法,但这并不完全相同。如果array.foo确实存在,但条件是false0(或可能还有其他值),则条件也将评估为false

issetJavaScript 与PHP的完美等同是什么?

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

我通常使用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操作员会返回,该方法在原型链中定义,因为它继承了form truetoStringobjObject.prototype

使用旧的线程,但是有新的方法可以运行等效线程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
  }
}

说明

的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.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 (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()哪种有效,但我个人避免使用

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

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

谢谢您的阅读!

参考资料

    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

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

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

function isset(str) {
    return window[str] !== undefined;
}
//
//  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;

 } 
//
//

我总是使用此通用函数来防止对原始变量以及数组和对象产生错误。

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
}

这个解决方案对我有用。

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

这是一个测试变量是否存在的防弹解决方案:

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

即使没有将for的y值传递给function test,我们的isset函数在这种情况下也可以完美运行,因为y在函数中test称为undefinedvalue。

(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

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
}

提供对象路径作为字符串,然后您可以将此字符串分解为路径并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
);

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

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

尝试在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

当我访问对象的更深的属性时,这对我来说确实是一个问题,因此我创建了一个函数,该函数将返回该属性值(如果存在),否则将返回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>
if (var) {
  // This is the most concise equivalent of Php's isset().
} 

PHP手册说:

isset —确定是否设置了变量并且不为NULL

并进行如下操作:

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

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

TRUE如果var存在并且具有除以外的其他值,则isset()返回NULLFALSE除此以外。

一些例子:

$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还检查varable是否 NULL

例如

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

因此,我们可以将其合并到javascript中,如下所示:

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

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

在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 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
}
    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;
        }
    }
本文地址:http://javascript.askforanswer.com/dengtongyujavascript-isset.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!