当前位置:   article > 正文

js 数字类型的字符串自动加1_你不一定了解的js数据类型

js 拿到后台的long类型后自动+1

fb732f560d6834b3df10d960d97489f9.png

上篇文章聊了js两种数据类型的区别以及基本数据类型,这篇文章主要聊一下js的引用数据类型、包装对象、js的强转换、隐性数据类型转换。

一、引用数据类型

ECMAScript中,引用类型是一种数据结构,用于将数据和功能组织在一起。

除了对象,引用数据类型还有很多:

  1. Array 数组
  2. Date 日期
  3. RegExp 正则
  4. Function 函数

除了上面的数据类型,还有三个比较特殊的(基本数据类型的包装对象):

包装对象

  1. Boolean
  2. Number
  3. String

大家可能遇到过一道面试题:

  1. let num1 = 3
  2. let num2 = new Number(3)
  3. console.log(num === num2) // false

这个Number()就是基本数据类型的number的包装对象:

  1. typeof(num1) // number
  2. typeof(num2) // object

这两个不是一个东西,当然也不相等了,那么我们就来搞清楚,这个包装对象到底是干什么的?

  1. let str = 'wanghuahua'
  2. let str1 = str.substr(0, 4)
  3. console.log(str1) // wang
  4. console.log(String.substr) // undefined

刚才调用substr方法截取了一下str这个字符串,str是基本数据类型,打印String的substr方法是undefined,这说明String是没有substr方法的,但是为什么能够截取呢?

这中间有一个计算机的操作,我们把它称作‘加工厂’,那么这个加工厂进行了哪些操作呢?(重点)

  1. 1、原材料进厂:把基本数据类型转成包装对象
  2. 因为基本数据类型是没有方法的,如果你想操作基本数据类型,那就必须转成包装对象
  3. 2、加工:调用substr的相关方法
  4. 包装对象是可以加方法和属性,所以这个时候包装对象会调用方法进行操作
  5. 3、成品出厂:包装对象转成基本数据类型
  6. ECMAScript规范中提供了toPrimitive原则,所以这个地方会遵从toPrimitive原则进行转换。

上篇文章说到了,这个js弱类型语言把相当多的操作都交给了计算机,这个地方就是一个明显的栗子,这些操作就都交给了计算机,相对来说增加了计算机的负担。

包装对象的由来,其实也没有那么复杂,就是为了处理基本数据类型的数据,加了中间的一层。

刚才在说成品出厂的时候,聊到了toPrimitive,toPrimitive就是我们常说的js强制转换:

二、js强制转换

所谓强制转换,就是人为的进行转换:

(一)toString() 转成字符串

  1. let num2 = new String('hhh')
  2. console.log(num2.toString()) // hhh

每个对象都有一个 toString()方法,当对象被表示为文本值时或者当以期望字符串的方式引用对象时,该方法被自动调用。

有时候会有一些非常恶心的面试题,这儿也列举几个不常见的:

  1. console.log(null.toString()) // 报错
  2. console.log(undefined.toString()) // 报错
  3. console.log(true.toString()) // 'true'
  4. let a = 4
  5. console.log(a.toString()) // 4
  6. console.log('hhh'.toString()) // 'hhh'
  7. console.log(Symbol().toString()) // 报错

除此之外,toString()还接收数字参数,来代表转换的进制:

  1. 二进制:.toString(2);
  2. 八进制:.toString(8);
  3. 十进制:.toString(10);
  4. 十六进制:.toString(16);

(二)valueOf() 返回原始值

  1. let num2 = new String('hhh')
  2. console.log(num2.valueOf()) // hhh

JavaScript 调用 valueOf()方法用来把对象转换成原始类型的值(数值、字符串和布尔值)。但是我们很少需要自己调用此函数,valueOf 方法一般都会被 JavaScript 自动调用。

  1. String => 返回字符串
  2. Number => 返回数字
  3. Date => 返回时间戳
  4. Boolean => 返回Boolean的this值
  5. Object => 返回this

上面两种方法都是object的方法,除了这两个方法之外,还有三个运算符:

(三)Number运算符 尽量搞成数字

  1. null 转换为 0
  2. undefined 转换为 NaN
  3. true 转换为 1false 转换为 0
  4. 字符串转换时遵循数字常量规则,转换失败返回NaN

(四)String运算符 全部转成字符串

刚才看toString的时候,null和undefined都会报错,但是String就不会报错,万物皆可转,(也不是那么绝对)但是String运算符没办法接收参数。

  1. String(null) // null
  2. string(undefined) // undefined

(五)Boolean运算符 全部转成true或者false

Boolean也很好理解,就是转成布尔值,只需要记住,一下几种转成false,其余的全部是true就行了。

  1. undefined
  2. null
  3. -0
  4. 0+0
  5. NaN
  6. ''(空字符串)

除了这六种,其余全部都是true,什么空对象,空数组全部都是true,甚至这种:

Boolean(new Boolean(false)) // true

(六)ToPrimitive运算符 转换成原始值

除了上面五种方法,js还有一个相对综合了一下的ToPrimitive,它对基础数据类型是没用的,只有引用数据类型可以。

ToPrimitive(obj,type)

ToPrimitive运算符接受一个需要转换的对象值,以及一个可选择的type值,根据这个可选的type值,来进行转换:

  1. typestring:
  2. 先调用obj的toString方法,如果为原始值,则return,否则进行第2
  3. 调用obj的valueOf方法,如果为原始值,则return,否则进行第3
  4. 抛出TypeError 异常
  5. typenumber:
  6. 先调用obj的valueOf方法,如果为原始值,则return,否则进行第2
  7. 调用obj的toString方法,如果为原始值,则return,否则第3
  8. 抛出TypeError 异常
  9. type参数为空
  10. 该对象为Date,则type被设置为String
  11. 否则,type被设置为Number

三、隐式数据类型转换

因为js是所类型语言,所以相对语法非常宽松,字符串可以和数字运算,数字还能和布尔值运算,在运算过程中就产生了隐式数据类型转换,首先,隐式转换有下面三个原则:

1、遇到+(字符串连接符)就转成string类型:

2、转成number类型:

  1. ++/--(自增自减运算符)
  2. + - * / %(算术运算符)
  3. > < >= <= == != === !=== (关系运算符)

3、遇到 !(逻辑非运算符),就转成boolean类型:

但是,这里面还有很多常见的坑,比如:

1、字符串拼接的+和算数运算符的+都是+,到底是哪个?

  1. 常见的面试题:
  2. console.log(1 + 'true') // '1true'
  3. console.log(1 + true) // 2
  4. console.log(1 + null) // 1
  5. console.log(1 + undefined) // NaN
  6. console.log(null + undefined) //NaN

关于字符串拼接+和算数运算符+,有个原则,只要有一边是字符串,那这个+就是字符串拼接符,其余的所有的情况都是算数运算符。

  1. console.log(1 + 'true') // '1true'
  2. 'true'是字符串,所以是字符串拼接,只要是字符串拼接,两边都会调用String运算符
  3. console.log(1 + true) // 2 Number(1)+Number(true) 1+1 2
  4. console.log(1 + null) // 1 Number(1)+Number(null) 1+0 1
  5. console.log(1 + undefined) // Number(1)+Number(undefined) 0+undefined NaN
  6. console.log(null + undefined) //Number(null)+Number(undefined) 0+undefined NaN
  7. 上面的没有一边是字符串,所以是运算符,如果被当做运算符,那么两边都会调用Number运算符

2、关系运算符,为什么2<'10','2'>'10'?

  1. 常见的面试题:
  2. console.log(2>'10') // false
  3. console.log('2'>'10') // true

如果关系运算符一边是字符串,那么会调用Number运算符,把两边转成数字,再比较

如果关系运算符两边都是字符串,会用charCodeAt()方法转成数字,再比较

  1. console.log(2>'10') // Number(2)>Number(10) 2>10 false
  2. console.log('2'>'10') //2.charCodeAt()>10.charCodeAt() 50>49 true

'2'>'10'进行charCodeAt()的时候,会先比第一个字节,如果不一样,直接就返回结果,如果第一个一样会接着比第二个字节。就是2.charCodeAt()会先跟1.charCodeAt()进行比较。

3、引用数据类型在进行隐式转换的时候,会先转成string。

  1. console.log([1,2] == '1,2') //true
  2. 在这个过程中[1,2]是引用数据类型,会先调用valueOf()方法
  3. 如果返回的还是引用数据类型,再调用toString()方法

4、逻辑非运算符和关系运算符,为啥[] == 0,![] == 0?(重点)

入门级别:

  1. console.log([] == 0) // true
  2. console.log(![] == 0) // true

为啥[]等于0,![]也等于0,这不是毁三观吗?

首先分析下[] == 0:

  1. 1、在讲引用数据类型阴性转换的时候,我们说了引用数据类型进行隐形类型转换必须先转成string
  2. [].valueOf().toString() // ''
  3. 2==数据关系运算符,两边必须都转成Number
  4. Number('') // 0
  5. 所以true

然后分析下![]为啥也是0:

  1. 1、在讲Boolean运算符的时候说了
  2. 除了undefined、null、-00+0、NaN、''(空字符串),其余全部都是true
  3. 所以[]是true,那么![]就是false
  4. 2、两边在转Number的时候:
  5. Number(false) // 0
  6. 所以![] == 0也是true

进阶级别

  1. [] == ![] //true
  2. [] == [] // false

[]等于非[]竟然是true,[]等于他自己反倒是false?

[] == ![]

  1. 1、[]还是会转成string,就是'''
  2. 2、![]还是false
  3. 3、‘’和false都进行Number操作都是0
  4. 所以相等

[] == [](这是个坑)

这个在上一篇讲栈内存的时候说了,引用数据类型在栈中存的都是地址,所以这两个肯定不一样

高阶级别

  1. {} == !{} // false
  2. {} == {} // false

{}和[]都是引用数据类型,为啥他是false呢?

{} == !{}

  1. 1、{}还是会转成string,但是{}转成字符串是""[object Object]"
  2. 2、![]还是false
  3. 3、Number(""[object Object]")和Number(false)
  4. 所以不相等

{} = {}

同理,也是比较栈内存的地址,所以false

关于js的数据类型,主要的就是隐性数据类型转换,会经常出错,这个系列的两篇文章主要是聊了一下js的赋值和赋址的区别、强转换以及隐性转换我们经常出现的问题。

个人的微信公众号:小Jerry有话说,平时会发一些技术文章和读书笔记,欢迎交流。

后面会持续更新一些js基础的文章,有兴趣的可以点个关注。

680d747cb783d0da05542a3986e57bad.png
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/63506
推荐阅读
相关标签
  

闽ICP备14008679号