是否有一种通用的JavaScript函数,可以检查变量是否具有值,并确保它不是undefined
或null
?我有这段代码,但我不确定它是否涵盖了所有情况:
function isEmpty(val){
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
是否有一种通用的JavaScript函数,可以检查变量是否具有值,并确保它不是undefined
或null
?我有这段代码,但我不确定它是否涵盖了所有情况:
function isEmpty(val){
return (val === undefined || val == null || val.length <= 0) ? true : false;
}
你有点过度了。为了检查一个变量是否没有被赋值,你只需要检查它是否等于undefined和null。
function isEmpty(value){
return (typeof value === "undefined" || value === null);
}
假设 0
,""
和对象(甚至是空对象和数组)都是有效的“值”。
null
的比较一直都具有这种确切的行为;这个函数等同于你的函数:let isEmpty = val => val == null;
- Gershom Maes我不建议尝试定义或使用一个计算整个世界中任何值是否为空的函数。什么才是真正的“空”呢?如果我有 let human = { name: 'bob', stomach: 'empty' }
,那么isEmpty(human)
应该返回true
吗?如果我有let reg = new RegExp('');
,那么isEmpty(reg)
应该返回true
吗?那么isEmpty([ null, null, null, null ])
呢?这个列表只包含空值,那么这个列表本身是否为空呢?我想在这里提出一些关于JavaScript中“vacuousness”的注解(故意使用模糊的词语以避免先前存在的关联),并且我想主张:我们永远不应该用通用方式处理JavaScript值中的“vacuousness”。
为了确定值的“vacuousness”,我们需要适应JavaScript内置、固有的感知值是“truthy”还是“falsy”。自然地,null
和undefined
都是“falsy”的。较为不自然的是数字0
(没有其他数字除了NaN
)也是“falsy”的。最不自然的是:''
是“falsy”的,但[]
和{}
(以及new Set()
和new Map()
)都是“truthy”的-尽管它们看起来都一样空!
还有一些关于null
与undefined
的讨论-我们是否真的需要两者来表达程序中的“vacuousness”?我个人避免在代码中出现undefined
。我总是使用null
表示“vacuousness”。尽管如此,我们仍然需要适应JavaScript内置的感知方式,即null
和undefined
的区别:
undefined
undefined
:let f = a => a;
console.log(f('hi'));
console.log(f());
undefined
时,具有默认值的参数才会接收默认值,而不是null
:let f = (v='hello') => v;
console.log(f(null));
console.log(f(undefined));
null
是一种明确的空值标识符;“本应填写的内容被有意留空”。实际上,undefined
是一种必要的复杂性,允许某些 JavaScript 特性存在,但在我看来,它应该始终留在幕后,不直接与之交互。我们可以将 undefined
看作是 JavaScript 实现默认函数参数的机制。如果您不向函数提供参数,那么它将接收一个值为 undefined
的参数。如果该参数最初设置为 undefined
,则会应用默认值到函数参数中。在这种情况下,undefined
是默认函数参数的关键,但它仍然处于后台:我们可以在不引用 undefined
的情况下实现默认参数功能。
以下是一种与 undefined
直接交互的糟糕默认参数实现:
let fnWithDefaults = arg => {
if (arg === undefined) arg = 'default';
...
};
这是一个很好的实现:
let fnWithDefaults = (arg='default') => { ... };
这是一种不好的接受默认参数的方式:
fnWithDefaults(undefined);
fnWithDefaults();
你是否有一个带有多个参数的函数,同时想要为某些参数提供值,而对于其他参数则接受默认值?
例如:
let fnWithDefaults = (a=1, b=2, c=3, d=4) => console.log(a, b, c, d);
a
和 d
提供值,并接受其他参数的默认值,应该怎么做?这似乎是错误的:fnWithDefaults(10, undefined, undefined, 40);
fnWithDefaults
以接受一个单一的对象:let fnWithDefaults = ({ a=1, b=2, c=3, d=4 }={}) => console.log(a, b, c, d);
fnWithDefaults({ a: 10, d: 40 }); // Now this looks really nice! (And never talks about "undefined")
我认为我们不应该以泛化的方式处理空值。相反,我们应该始终具有严谨性,在确定数据是否为空值之前获取更多信息 - 我主要通过检查我正在处理的数据类型来实现这一点:
let isType = (value, Cls) => {
// Intentional use of loose comparison operator detects `null`
// and `undefined`, and nothing else!
return value != null && Object.getPrototypeOf(value).constructor === Cls;
};
value
是Cls
的直接实例,而不是Cls
的子类的实例。我避免使用instanceof
有两个主要原因:
([] instanceof Object) === true
(“数组是对象”)('' instanceof String) === false
(“字符串不是字符串”)Object.getPrototypeOf
用于避免(晦涩的)边缘情况,例如let v = { constructor: String };
对于isType(v, String)
(false)和isType(v, Object)
(true),isType
函数仍然返回正确值。isType
函数以及以下提示:
let v = JSON.parse(someRawValue);
,我们的v
变量现在是未知类型。尽早限制可能性是最好的方式。最好的方法是通过要求特定类型来实现:例如if (!isType(v, Array)) throw new Error('Expected Array');
- 这是一种非常快速和表达力强的方式,可以消除v
的通用性,并确保它始终是一个Array
。但有时候,我们需要允许v
具有多种类型。在这些情况下,我们应该尽早创建代码块,在其中v
不再是通用的:if (isType(v, String)) {
/* v isn't generic in this block - It's a String! */
} else if (isType(v, Number)) {
/* v isn't generic in this block - It's a Number! */
} else if (isType(v, Array)) {
/* v isn't generic in this block - it's an Array! */
} else {
throw new Error('Expected String, Number, or Array');
}
if (v === null) throw new Error('Null value rejected');
- 这很好,可以确保null
值不会被通过,但如果一个值确实被通过了,我们仍然几乎不知道它的任何信息。通过这个null-check的值v
仍然非常通用 - 它是除了null
之外的任何东西!黑名单几乎无法消除通用性。null
,否则永远不要考虑“空值”。相反,考虑“一个为空的X”。 实际上,永远不要考虑做任何类似于if (isEmpty(val)) { /* ... */ }
的事情 - 无论这个isEmpty
函数如何实现(我不想知道...),它都是没有意义的!而且它太过通用了!只有了解val
的类型,才能计算它是否为空。检查空值应该像这样:
“一个没有字符的字符串”:if (isType(val, String) && val.length === 0) ...
“一个没有属性的对象”:if (isType(val, Object) && Object.entries(val).length === 0) ...
“一个小于等于零的数字”:if (isType(val, Number) && val <= 0) ...
“一个没有项目的数组”:if (isType(val, Array) && val.length === 0) ...
唯一的例外是当null
用于表示某些功能时。在这种情况下,说“一个空值”是有意义的:if (val === null) ...
可能最简短的答案是
val==null || val==''
如果你将右边改为val === ''
,那么空数组将会返回false。证明如下:
function isEmpty(val){
return val==null || val==''
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
关于==
的更多细节(源自这里)
BONUS: 为什么===
比==
更清晰
为编写清晰易懂的代码,请使用明确列出可接受值的列表
val===undefined || val===null || val===''|| (Array.isArray(val) && val.length===0)
function isEmpty(val){
return val===undefined || val===null || val==='' || (Array.isArray(val) && val.length===0)
}
// ------------
// TEST
// ------------
var log = (name,val) => console.log(`${name} -> ${isEmpty(val)}`);
log('null', null);
log('undefined', undefined);
log('NaN', NaN);
log('""', "");
log('{}', {});
log('[]', []);
log('[1]', [1]);
log('[0]', [0]);
log('[[]]', [[]]);
log('true', true);
log('false', false);
log('"true"', "true");
log('"false"', "false");
log('Infinity', Infinity);
log('-Infinity', -Infinity);
log('1', 1);
log('0', 0);
log('-1', -1);
log('"1"', "1");
log('"0"', "0");
log('"-1"', "-1");
// "void 0" case
console.log('---\n"true" is:', true);
console.log('"void 0" is:', void 0);
log(void 0,void 0); // "void 0" is "undefined" - so we should get here TRUE
(这里是源代码链接)
- Kamil Kiełczewski以下是我的代码 - 如果值为null、undefined等或为空(即只包含空格),则返回true:
function stringIsEmpty(value) {
return value ? value.trim().length == 0 : true;
}
/**
* Checks if `value` is empty. Arrays, strings, or `arguments` objects with a
* length of `0` and objects with no own enumerable properties are considered
* "empty".
*
* @static
* @memberOf _
* @category Objects
* @param {Array|Object|string} value The value to inspect.
* @returns {boolean} Returns `true` if the `value` is empty, else `false`.
* @example
*
* _.isEmpty([1, 2, 3]);
* // => false
*
* _.isEmpty([]);
* // => true
*
* _.isEmpty({});
* // => true
*
* _.isEmpty('');
* // => true
*/
function isEmpty(value) {
if (!value) {
return true;
}
if (isArray(value) || isString(value)) {
return !value.length;
}
for (var key in value) {
if (hasOwnProperty.call(value, key)) {
return false;
}
}
return true;
}
_.isEmpty(value)
window
дёҠжІЎжңү isArray
жҲ– isString
еҮҪж•°гҖӮ - GFoley83return val || 'Handle empty variable'
使用这种方法能够在很多地方更加清晰简洁地处理。同时,也可以用于变量的赋值。
const res = val || 'default value'
true
且您正在尝试提供或返回false
的val
时不行。 - Molombyconst res = falsyValue ? true : falsyValue
- cubefox如果变量没有被声明,你将无法使用函数测试未定义的变量,因为会出现错误。
if (foo) {}
function (bar) {}(foo)
如果foo没有被声明,两者都会生成错误。
如果您想测试变量是否已声明,可以使用
typeof foo != "undefined"
如果你想测试 foo 是否已经被声明并且有一个值,可以使用以下方法:
if (typeof foo != "undefined" && foo) {
//code here
}
??
来检查null
和undefined
值。请参阅MDN文档。null ?? 'default string'; // returns "default string"
0 ?? 42; // returns 0
(null || undefined) ?? "foo"; // returns "foo"
这可能会有用。
数组中的所有值都代表您想要的内容(null、undefined或其他内容),您需要在其中搜索您想要的内容。
var variablesWhatILookFor = [null, undefined, ''];
variablesWhatILookFor.indexOf(document.DocumentNumberLabel) > -1
function isEmpty(obj) {
if (typeof obj == 'number') return false;
else if (typeof obj == 'string') return obj.length == 0;
else if (Array.isArray(obj)) return obj.length == 0;
else if (typeof obj == 'object') return obj == null || Object.keys(obj).length == 0;
else if (typeof obj == 'boolean') return false;
else return !obj;
}
在ES6中,使用trim函数处理空格字符串:
const isEmpty = value => {
if (typeof value === 'number') return false
else if (typeof value === 'string') return value.trim().length === 0
else if (Array.isArray(value)) return value.length === 0
else if (typeof value === 'object') return value == null || Object.keys(value).length === 0
else if (typeof value === 'boolean') return false
else return !value
}
(truthy statement) ? true : false;
。直接写成(truthy statement);
即可。 - David Baucumif (hungry) …
而不是if (hungry === true) …
。就像所有编码风格一样,这只是个人审美问题。更具体地说,对于 OP 提供的例子,他更冗长地表达了“如果它为真,则为真,如果不为真,则为假”,但如果它为真,则已经是真的。如果它为假,则已经是假的。这相当于说:“如果你饿了,那么你就饿了,如果不饿,那么你就不饿。” - David Baucum