注册
web

我做梦都想不到😵,我被if(x)摆了一道!



读本文,可以收获什么?


字数:2494 花费时间:5min


if(x)中的x为各种类型的数据或者值的时候会发生什么?x为各种数据类型、表达式、特殊值、位运算、函数等值的时,这些在if语句都充当了什么,实现了什么?


总结== === ≠三种情况特殊值的比较,如下图所示:



image.png


作为一个程序员的我们,相信我们写代码用的最多逻辑应该就是if语句了吧,其实我们真的了解if(x)究竟发生了什么?其实很简单,我们可能都知道中文有这样一个模板:"如果是什么,就会做什么",也就是说符合条件的某件事,才会去做某件事。同样的道理if(x)的意思就是如果符合x条件,我们就可以执行if语句块的代码了。而我们JavaScript中的哪个数据类型是涉及是否意思的?当然是Boolean类型啦,其实if内的x非布尔值都会做一次Boolean类型的转换的


1 x为一个值时


1.1 x为字符串:


x为一个空字符串时,这是一个假值,if语句会转换为false。


if ("") {
console.log("Hello World!");
}
console.log(Boolean(""));// false

x为一个非空字符串是,这是一个真值。if语句会转换为true。


if (!"") {
console.log("Hello World!");// Hello World!
}
console.log(Boolean(!""));// true

x为一个空格字符串,这是一个真值。if语句会转换为true。否则会转换为false


if (" ") {
console.log("Hello World!");// Hello World!
}
console.log(Boolean(" "));// true
if (!" ") {
console.log("Hello World!");
}
console.log(Boolean(!" "));// false

x为一个字符串,这是一个真值。if语句会转换为true。否则会转换为false


if ("JavaScript") {
console.log("Hello World!");// Hello World!
}
console.log(Boolean("JavaScript"));// true

if (!"JavaScript") {
console.log("Hello World!");
}
console.log(Boolean(!"JavaScript"));// false

1.2 x为数字


x为一个数字0时,这是一个假值,if语句会转换为false。x为一个数字!0时,这是一个真值,if语句会转换为true。


if (0) {
console.log("Hello World")
}
console.log(Boolean(0));// fasle

if (!0) {
console.log("Hello World");// Hello World
}
console.log(Boolean(!0));// true

if (1) {
console.log("Hello World") // Hello World
}
console.log(Boolean(1));// true

if (!1) {
console.log("Hello World")
}
console.log(Boolean(!1));// false

if (-0) {
console.log("Hello World")
}
console.log(Boolean(-0));// fasle
if (!-0) {
console.log("Hello World");// Hello World
}
console.log(Boolean(!-0));// true

1.3 x为数组


x为一个空数组,这是一个真值,if语句会转换为true。


if ([]) {
console.log("Hello World");// Hello World
}
console.log(Boolean([]));// true
if (![]) {
console.log("Hello World");
}
console.log(Boolean(![]));// false

x为一个嵌套空数组时,这是一个真值,if语句会转换为true。否则是假值。if语句会转换为false


if ([[]]) {
console.log("Hello World");// Hello World
}
console.log(Boolean([[]]));// true
if (![[]]) {
console.log("Hello World");
}
console.log(Boolean(![[]]));// false

x为一个有空字符串的数组时,这是一个真值,if语句会转换为true。否则是假值。if语句会转换为false。


if ([""]) {
console.log("Hello World");// Hello World
}
console.log(Boolean([""]));// true
if (![""]) {
console.log("Hello World");
}
console.log(Boolean(![""]));// false

x为一个有数字0的数组时,这是一个真值,if语句会转换为true。否则是假值。if语句会转换为false。


if ([0]) {
console.log("Hello World");// Hello World
}
console.log(Boolean([0]));// true
if (![0]) {
console.log("Hello World");
}
console.log(Boolean(![0]));// false

1.4 x为对象:


if ({}) {
console.log("Hello World") // Hello World
}
console.log(Boolean({}));// true

2 x为特殊值时


if (null) {
console.log("Hello World");
}
console.log(Boolean(null));// false

if (undefined) {
console.log("Hello World");
}
console.log(Boolean(undefined));// false

if (NaN) {
console.log("Hello World");
}
console.log(Boolean(NaN));// false

3 x为位运算时


if (true | false) {
// 按位或,只要有一个成立就为true
console.log("Hello World");
}
console.log(Boolean(true | false));// true

4 x为表达式时


比较的相方首先调用ToPrimitive(内部函数,不能自行调用)转换为原始值,如果出现非字符串,就根据ToNumber规则将双方强制转换为数字来进行比较。


const a = [42];
const b = ["43"];
console.log(a < b);// true

5 x为等式时


5.1 一个等号(=)


=: 一个等号代表的是赋值,即使x的值为a=2,也就是说变量的声明操作放在if判断位置上了,其实它还是一个变量并不是一个操作。


let a;
if (a = 2) {
console.log("条件成立!");// 条件成立!
}
console.log(a);// 2

let a;
if (a = 2) {
console.log("条件成立!");// 条件成立!
}
console.log(typeof (a = 2));// number
console.log(Boolean(a = 2));// true

let a;
if (a = 2 && (a = 3)) {
console.log("条件成立!");// 条件成立!
}

console.log(typeof (a = 2 && (a = 3)));// number;

5.2 两个等号(==)


==:宽松相等,我们可能都会这样想,==检查值是否相等,听起来蛮有道理,但不准确,真正的含义是==允许相等比较重进行强制类型转换



对于==符号尽量遵守两个原则:


如果两边的值中有true或者false,千万不要使用==


如果两边的值中有[]、""、0,尽量不要使用==





  • 两个值类型相同,则执行严格相等变量。


    🍟 都是字符串类型:


    const a = "";
    const b = "12";
    console.log(a == b);// false

    🍟 都是NaN类型:全称为not a number,理解为不是一个数值。JavaScript的规定, NaN表示的是非数字, 那么这个非数字可以是不同的数字,因此 NaN 不等于 NaN。


    const a = NaN;
    const b = NaN;
    console.log(a == b);// false

    🍟 都是Symbol类型:Symbol命名的属性都是独 一无二的,可以唯一标识变量值,不受是否相同变量值。


    const a = Symbol("1");
    const b = Symbol("1");
    console.log(a == b);// false

    🍟 都是对象类型。对象的比较是内存地址,因为对象是存储在堆中,当堆中有对象时,它会相对应内存中有一个存储的地址,在栈中其存储了其在堆中数据的地址,当调用数据时,去堆中调取对应堆中的数据的地址获取出来。也就是相同对象比较的是内存地址,变量不一样存储位置不一样。


    const a = { a: 1 };
    const b = {};
    console.log(a == b);// false

    const a = {};
    const b = {};
    console.log(a == b);// false
    console.log(Boolean(a));// true



  • 两个值类型不相同。


    🍟 一个值是null,一个是undefind。


    const a = undefined;
    const b = null;
    console.log(a == b);// true

    🍟 一个值是数字,一个值是字符串。字符串强制转换为数字在比较。


    const a = 12;
    const b = "12";
    console.log(a == b);// true

    🍟 一个值是布尔值,一个是其他类型的值。这种做法是不安全,不建议去使用,在开发中尽量不要这样使用。


    console.log("0" == false);// true
    console.log("" == false);// true
    console.log(0 == false);// true
    console.log([] == false);// true

    🍟 一个值是对象,一个值是字符串或数字。对象与非对象的比较,对象会被强制转换原始值(通过内部函数 ToPrimitive自动执行,这个是内部函数不能直接调用)再比较。


    const a = {};
    const b = "";
    console.log(a == b);// false



5.3 三个等号(===)


===: 严格相等,我们可能都会这样想,===检查值和类型是否相等,听起来蛮有道理,但不准确,真正的含义是===不允许相等比较重进行强制类型转换,也就是不做任何处理变量是什么就是什么。


const a = 0;
const b = "0";
console.log(a === b);// false

6 x为&&、||操作时


||和&&首先会对第一个操作数(a和c)执行条件判断,如果其不是布尔值(如上例)就先进行ToBoolean强制类型转换,然后再执行条件判断。


🍟 对于||来说,如果条件判断结果为true就返回第一个操作数(a和c)的值,如果为false就返回第二个操作数(b)的值。


const a = 12;
const b = "abc";
const c = null;
if (a || b) {
console.log("a||b");// a||b
}
console.log(typeof (a || b));// number
console.log(Boolean(a || b));// true
console.log(a || b);// 12

const b = "abc";
const c = null;
if (c || b) {
console.log("c||b");// c||b
}
console.log(typeof (c || b));// string
console.log(Boolean(c || b));// true
console.log(c || b);// abc

🍟 &&则相反,如果条件判断结果为true就返回第二个操作数(b)的值如果为false就返回第一个操作数(a和c)的值。


const a = 12;
const b = "abc";
if (a && b) {
console.log("a&&b");// a&&b
}
console.log(typeof (a && b));// string
console.log(Boolean(a && b));// true
console.log(a && b);// abc

const b = "abc";
const c = null;
if (c && b) {
console.log("c&&b");
}
console.log(typeof (c && b));// object
console.log(Boolean(c && b));// false
console.log(c && b);// null

7 x为函数判断时




  • typeof与instanceof的区别


    🍟 typeof:返回值是一个字符串,用来说明变量的数据类型。一般只能返回如下几个结果:number、string、function、object、undefined,对于Array、Null等特殊对象typeof一律返回object,这正是typeof的局限性。


    console.log(typeof undefined == 'undefined');// true
    console.log(typeof null);// object

    🍟instanceof:返回值为布尔值,用来测试一个对象在其原型链中是否存在一个构造函数的prototype属性。用于判断一个变量是否某个对象的实例。,注意地,instanceof只能用来判断对象和函数,不能用来判断字符串和数字等


    const arr = new Array()
    if (arr instanceof Array) {
    console.log("arr instanceof Array");// arr instanceof Array
    }
    if (arr instanceof Object) {
    // 因为Array是Object的子类
    console.log("arr instanceof Object");// arr instanceof Array
    }
    console.log(typeof (arr instanceof Array));// boolean

    🍟 typeofinstanceof都有一定的弊端,并不能满足所有场景的需求。如果需要通用检测数据类型,可以使用Object.prototype.toString.call()方法:


    Object.prototype.toString.call({});// "[object Object]"
    Object.prototype.toString.call([]); // "[object Array]"
    Object.prototype.toString.call(666); // "[object Number]"
    Object.prototype.toString.call("xxx"); // "[object String]"



注意,该方法返回的是一个格式为"[object Object]"的字符串。




  • indexof与includes区别


    🍟 indexof:返回的是所含元素的下标,注意地,此函数是无法判断是否有NaN元素


    const str = "130212";
    if (str.indexOf("0")) {
    console.log("str中存在0!")
    }
    console.log(str.indexOf("0"));// 2

    🍟 includes:返回的是布尔值,代表是否存在此元素。


    const str = "130212";
    if (str.includes("0")) {
    console.log("str中存在0!")
    }
    console.log(str.includes("0"));// true



作者:路灯下的光
来源:juejin.cn/post/7154647954840616996

0 个评论

要回复文章请先登录注册