深度剖析typeof和类型转换(如有细节纰漏和问题欢迎指正)

typeof和类型转换

我们首先来看看typeof的官方定义: 传入一个数据, typeof来帮你检测该数据的类型并且返回给你一个字符串类型的类型结果

小白们可能不是很懂, 毕竟官方文档也很少说人话, 大概意思也就说现在你有一个值, 你给他咣当扔进typeof里, typeof会返回给你这个值的数据类型

var a = 123; //我们很清楚知道这个是一个number类型的数据a
console.log(typeof(a)); //咣当扔进去, typeof会告诉你他是number, 所以会返给一个number出来

typeof会返回给我们六种数据类型结果: number, string, boolean, undefined, object, function

var num = 123; 
console.log(typeof(num)); // number

var str = 'helloworld'; 
console.log(typeof(str)); //string

var flag = true;
console.log(typeof(flag)); //boolean

var age;
console.log(typeof(age)); //已声明未赋值, undefined

function foo() {
    console.log('func');
}
console.log(typeof(foo)); //function

var obj = {};
console.log(typeof(obj)); //object

关于typeof的一些小细节

  1. typeof(数据) 可以直接简写成typeof 数据, 但是我们依然不建议这么做
console.log(typeof(123)); //number
console.log(typeof 123); //number
  1. 如果细心的同学会发现, 当我们typeof(null) 或者typeof(array)的时候也会返回object
console.log(typeof(null)); //object
console.log(typeof([])); //object

这是因为typeof返回object指的是一种泛泛的引用值, 所以当我们typeof array的时候也会返回object, 而null则是因为历史遗留问题, 在曾经null是用来给object占位的, 所以typeof null也会返回object

typeof的应用场景

可能在上面有些小白新手同学还是没办法理解到typeof的存在意义, 因为大家可能会像我定义了什么类型我还能不知道吗?要这typeof有啥用?
TvBp5jLA-1575269474332)(./imgs/ikownu.jpg)]

其实当未来我们接触的更加广泛以后, 我们需要跟后端交互数据, 或者是我们期望用户在填写表单的时候不要乱填, 比如我们从后端请求回来的数据是不是我们想要的啊,又比如让用户输入电话号码, 他给我们输入的是名字啊之类的, 我们可以用typeof简单检测一下, 当然未来还有更多更好的办法检测, 但是typeof在当下存在的意义就是如此

// 举个例子: 假设在页面中有一个input元素, 是用来让用户填写年龄的
var ageInput = document.getElementById('input'); 

if(typeof(ageInput.value) !== 'number') {
    alert('您好请输入正确的年龄信息');
}

// 当我们用typeof检测到用户没有输入数字类型的年龄的话我们就给用户一个相应的提示

typeof存在的意义还有很多, 这里就列举了一种, 往后随着业务经验越来越丰满, 对于这块的理解大家也会越来越深入

类型转换

显式类型转换

顾名思义, 类型转换就是把一个数据类型转化成另一个数据类型, 比如我把number类型的1转化为字符串类型的1, 这就是一种类型转换, 很好理解, 而显示类型转换是啥呢, 就是告诉你, 爷就是做类型转换的, 你按照我的规则用吧, 用了就可以转换了

显示类型转换的语法

  1. Number(mix)

Number会想方设法的把括号里的参数转化为数字并返回给你, 我们来看看一些实例

console.log(Number('123')); // 返回数字类型的123
console.log(Number(true)); //当遭遇布尔类型, true转化为1, false转化为0
console.log(Number(null)); //null会被转化为0
console.log(Number(undefined)); //undefined转化为NaN
console.log(Number('abc')); //这种看起来就不是数字的一定会转化为NaN
// ...

其他的小伙伴们可以自行尝试, 用法的话我相信大家可能已经理解了,这哥们不管你三七二十一看到东西就转化为数字,转化不了的他也要给你整成NaN
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9SqgCeDQ-1575269474333)(./imgs/anpai.jpg)]

  1. parseInt(string, radix)

parseInt的目的不是为了转化为数, 这家伙是要给你弄成整数, 来看几个例子

console.log(parseInt('123')); // 123
console.log(parseInt('123.3')); // 123
console.log(parseInt(true)); //NaN
console.log(parseInt(null)); // NaN
// ...

这哥们, 侧重点跟Number又不太一样, Number是跟疯了一样想尽一切办法给你转化为整数, 这哥们佛系的多, 看着像数字我才给你转, 你你看着都不像的我还管你干啥

我们可以看看parseInt的官方定义: parseInt致力把括号内的参数转化为整形数据, 他会从参数值的第一位开始看, 看到非数字位截止, 如果第一位就是非数字, 那么会直接返回NaN

console.log(parseInt('123.123')); //看到非数字为截止, 那么势必返回123
console.log(parseInt('123abc')); //返回123
console.log(parseInt('abc123')); //返回NaN

其实parseInt是可以传两个参数的, 第一个参数是要转化的数据, 第二个是radix, 称之为基底, 是啥意思呢? 就是说, 第二个参数填进制, 然后parseInt会以第二个参数为基底将第一个参数转化为十进制, 说人话就是会把你传的第一个参数用第二个参数作为进制转化为十进制

console.log(parseInt('10', 16)); //把字符串'10'当成16进制转化为十进制, 而16进制的10转化为10进制是16, 所以返回值16
console.log(parseInt('10', 2)); //把二进制的'10'转化为10进制是2, 所以返回值为2
  1. parseFloat(string)

parseFloat就简单多了, 没这么多套路

console.log(parseFloat('123.45abc')); // 123.45
console.log(parseFloat('123.3.4')); // 123.3
console.log(parseFloat('123.a')); //123
//...

parseFloat会将参数转换为浮点型的小数, 他的规则是看到除第一个点以外的非数字位截止, 比如出现两个点, 那第二个点肯定就是非数字位了, 就看不了了截断了

  1. toString(radix)

toString用法跟之前的有些不太一样, 他也是致力于把某个值变成字符串, 但是他的调用方式不大一样, 他谁想变成字符串, 谁就去调用他, 来看看实例

var num = 123;
console.log(num.toString());
var flag = true; 
console.log(flag.toString());
// ...

但是我们要知道, undefined和null是不能调用toString方法的, 具体是为什么的话相信对原型有了解的小伙伴是知道理由的, 而不知道也的也没关系, 我会有专门的博客写prototype,直接搜索就好了

同时toString接收一个参数, radix他跟parseInt的radix值是一样, 只是他两刚好相反, parseInt是把第二个参数当成第一个参数的基底来转化为十进制, 而toString是把调用他的值从十进制转化为参数的进制,说简单一点就是parseInt的radix是把数值从xx进制转化为10进制, 而toString是把调用他的数值从十进制转化为xx进制

var num = 10;
console.log(num.toString(2)); // 1010
console.log(num.toString(8));// 12
//...
  1. String(mix)

String会想方设法的把参数转化为字符串, 怎么变成字符串? 加个引号碰个瓷儿不就ok了

console.log(String(123)); //'123'
console.log(String(false)); //'false'
console.log(String(undefined)); //'undefined'
console.log(String(null)); //'null'
// ...

  1. Boolean(mix)
    Boolean就是试图把参数转化我为布尔值
console.log(Boolean('')); //false
console.log(Boolean('abc')); //true
console.log(Boolean(123)); //true
// ...

Boolean转化为布尔值的方式极其简单, 我们只需要记住他的规则,只有六个值会被转化为false, 其他的统统都是true

  • undefind
  • null
  • ‘’
  • 0
  • false
  • NaN

除了上面的六个值, 其他任何值你转化为布尔值都是true

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I3DOD5eI-1575269474333)(./imgs/free.jpg)]

隐式类型转换

所谓隐式类型转换, 就是在你进行某些操作的时候, 系统会帮你偷偷的进行类型转换, 说明白点: 显示类型转换就是爷就是给你转换了,你看着。 而隐式类型转换是他给你转换了你都不知道怎么换的

隐式类型转换, 他内部调用的都是显式类型转换的方法

  1. isNaN(mix) -----对应Number

isNaN接收一个参数, isNaN会判断这个参数是不是NaN, 如果不是NaN就返回false如果是就返回true, 那么他是怎么判断的呢

console.log(isNaN(NaN)); // true
console.log(isNaN(123)); //false
console.log(isNaN('123')); // false
console.log(isNaN('abc')); // true

其实isNaN的工作原理是, 他会先把参数放进Number里进行类型转化为number, 如果从Number里转化成number类型但是值为NaN的话, 那么他就会返回true, 反之返回false。

也就是说isNaN内部会隐式的调用Number方法进行类型转化

  1. ++/-- +/-(一元正负) ----对应Number
var a = '123';
a ++; //这个符号往这一立, 还没等你运算呢, 他先给你把变量a放进Number里转换一下再说
console.log(a); // 124

var b = '10';
b --;
console.log(b); // 9;

var c = 'abc';
c --;
console.log(c); //NaN

var d = 'abc';
console.log(-d); // NaN
  1. +(加号) ----根据不同的情况对应String或者Number
跟上面的一元正负有所不同, 加号的隐式类型转换比较复杂, 我们来看看实例
var a = 'a' + 1;
console.log(a); // 'a1'

var b = true + 1;
console.log(b); // 2
//...

加号的规则有所不同

  • 如果加号有一侧是字符串, 那么会把加号另侧的值都通过String转化为字符串进行连接

  • 如果加号两侧没有字符串, 那么加号会想法设法的把加号两侧的非number类型的数据转化为number类型的数字再进行运算

  • 这一块可能还存在其他的详细情况, 但是笔者忘记了, 如果没有甚好, 有的话欢迎补充

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-G0UDeL9I-1575269474334)(./imgs/fat.jpg)]

  1. -, * , /, % ----对应Number
// 所以我们会看到一些比较惊奇的现象
console.log('1' - 1); //0
console.log('2' * 4); //8
console.log('4' / 2); //2
//...
  1. && || ! ----对应Boolean

这三哥们咱们一个一个来说

console.log(1 > 0 && 2); //2 
&&与运算符, 这个运算符的规则是, 会先将第第一个遇见的值放进Boolean中转化为布尔值是否为true, 如果为true则往后看, 如果为false则返回该表达式的值, 如果一直到到最后一个还是true则直接返回最后一个
console.log(0 || 'yes'); // yes

||或运算符, 这个运算符的规则是, 会先将第第一个遇见的值放进Boolean中转化为布尔值是否为false, 如果为false则往后看, 如果为true则返回该表达式的值, 如果一直到到最后一个还是false则直接返回最后一个

console.log(!1); //false

!会把后面的表达式放进Boolean类型中拿到布尔值然后再进行取反
  1. <, >, <=, >= ----Number
console.log('1' > 2); //false

如果有一侧有字符串, 那么肯定会把字符串放进Number里淘一圈回来

  1. ==, != ----Number
console.log('0' == 0); //true
console.log(false == 0); //true
console.log(false > true); //false

会不讲道理一样的把两边的非number类型数据放进Number中转换一下再拿出来比

我们来看一些关于typeof和类型转换的题巩固一下知识

console.log(typeof(a)); //undefined
console.log(typeof(undefined)); //undefined
console.log(typeof(NaN)); //number
console.log(typeof(null)); //object
var a = '123abc';
console.log(typeof(+a)); //number
console.log(typeof(!!a)); //boolean
console.log(typeof(a + '')); //string
console.log(1 == '1'); //true
console.log(1 === '1'); //false
console.log(NaN == NaN); // false
console.log(typeof(typeof(undefined))); //string
console.log(NaN == undefined); //false
console.log('11' + 11); // 1111
console.log(parseInt('123abc')); //123
console.log(typeof(typeof(a))); //string

tips: NaN比较六亲不认, 他谁都不等于,疯起来连自己都不认识, 所以NaN 肯定不等于NaN

同时, typeof一个值会返回他的数据类型没错, 但是这个返回的数据类型的数据类型是string类型的, 而且typeof undefined 不会报错, 会返回一个字符串的undefined

typeof和类型转换到此为止, Thanks for reading, 代表个人理解和观点, 如有纰漏和问题欢迎指出

发布了33 篇原创文章 · 获赞 11 · 访问量 2266

猜你喜欢

转载自blog.csdn.net/weixin_44238796/article/details/103348783