基础数据类型
- Undefined
- Undefined类型只有一个唯一的字面值 undefined,表示给变量不存在
- 出现undefined出现的场景
- 使用只声明而未初始化的变量
- 获取对象的某个不存在的属性(自身属性和原型链继承属性)
- 函数没有明确的返回值,却在其他地方使用了返回值
- 函数定义时使用了多个形式参数,而在调用时传递的参数的数量少于形参数量,未匹配的参数就是undefined
- 出现undefined出现的场景
- Null
- 只有一个唯一的字面值null,表示一个空指针对象,这也是使用typeof运算法检测null值时,返object的原因。
- 出现场景
- 声明变量为了保存某个值时,应该赋值为null
- JavaScript在获取DOM元素时,没有找到指定的元素对象,返回null
- 使用正则表达式进行捕获时,没有捕获到结果,返回null
- Undefined和Null的异同点
- 相同点
- 都只有一个字面值
- 转换为Boolean类型时,值为false
- 转换成对象时,报错 TypeError的引用异常
- undefined派生自null类型,非严格相等下,两者相等
- 不同点
- null是JavaScript中的关键字,undefined是JavaScript中的一个变量
- typeof检测时,Null返回Object,undefined返回undefined
- 通过call调用toStrong()函数时,Undefined返回 “[object Undefined ]”, null返回“[object Null]”
- 字符串类型转换时,null转换为“null”,Undefined转换为“undefined”
- 数值类型转换,undefined转化为NaN,无法参与运算,null转换为0,可以参加运算
- 不能将一个变量显式的设置为undefined,应该使用定义为null
- 相同点
- Undefined类型只有一个唯一的字面值 undefined,表示给变量不存在
- Boolean
- 字面值: true和false,区分大小写
- if(a)中a的值会进行隐式转换
- 字符串转换为Boolean
- 空字符串””或者’’都会转换为false。· 任何非空字符串都会转换为true,包括只有空格的字符串” “。
- ·空字符串””或者’’都会转换为false。· 任何非空字符串都会转换为true,包括只有空格的字符串” “。
- 字符串转换为Boolean
- Number类型转换为Boolean类型·
- 0和NaN会转换为false。
- 除了0和NaN以外,都会转换为true,包括表示无穷大和无穷小的Infinity和-Infinity。
- Object类型转换为Boolean类型
- 当object为null时,会转换为false。
- 如果object不为null,则都会转换为true,包括空对象{}。
- Function类型转换为Boolean类型
- 任何Function类型的值都会转换为true。
- Null类型转换为Boolean类型
- Null类型只有一个null值,会转换为false。
- Undefined类型转换为Boolean类型
- Undefined类型只有一个undefined值,会转换为false。
- Number类型
- 类型介绍
- 八进制 0开头其他位是0-7
- 16进制 0x开头其他位是 0-9,a-f,A-F
- 类型转换
- Boolean类型转换为Number类型
- true转换为1。
- false转换为0。
- Null类型转换为Number类型
- Null类型只有一个字面值null,直接转换为0。
- Undefined类型转换为Number类型
- Undefined类型只有一个字面值undefined,直接转换为NaN。
- String类型转换为Number类型
- 如果字符串中只包含数字,则会转换成十进制数;如果前面有0,会直接省略掉,例如”0123”会转换为123。
- 如果字符串中包含的是有效的浮点数,则同样按照十进制转换,例如”1.23”会转换为1.23。
- 如果字符串中包含有效的十六进制格式,则会按照十进制转换,例如”0x3f”会转换为63。
- 如果是空字符串,则转换为0。·
- 如果字符串中包含了除上述格式以外的字符串,则会直接转换为NaN。
- Object类型转换为Number类型
- Object类型在转换为Number类型时,会优先调用valueOf()函数,然后通过valueOf()函数的返回值按照上述规则进行转换。如果转换的结果是NaN,则调用toString()函数,通过toString()函数的返回值重新按照上述规则进行转换;如果有确定的Number类型返回值,则结束,否则返回“NaN”。
- Boolean类型转换为Number类型
- Number()函数
- Number()函数可以用于将任何类型转换为Number类型,它在转换时遵循下列规则。
- 如果是数字,会按照对应的进制数据格式,统一转换为十进制并返回。
- 如果是Boolean类型的值,true将返回为“1”,false将返回为“0”。
- 如果值为null,则返回“0”。
- 如果值为undefined,则返回“NaN”。
- 如果值为字符串类型,则遵循下列规则。
- 如果该字符串只包含数字,则会直接转换成十进制数;如果数字前面有0,则会直接忽略这个0。
- 如果字符串是有效的浮点数形式,则会直接转换成对应的浮点数,前置的多个重复的0会被清空,只保留一个。
- 如果字符串是有效的十六进制形式,则会转换为对应的十进制数值。
- 如果字符串是有效的八进制形式,则不会按照八进制转换,而是直接按照十进制转换并输出,因为前置的0会被直接忽略。
- 如果字符串为空,即字符串不包含任何字符,或为连续多个空格,则会转换为0。
- 如果字符串包含了任何不是以上5种情况的其他格式内容,则会返回“NaN”。
- 如果值为对象类型,则会先调用对象的valueOf()函数获取返回值,并将返回值按照上述步骤重新判断能否转换为Number类型。如果都不满足,则会调用对象的toString()函数获取返回值,并将返回值重新按照步骤判断能否转换成Number类型。如果也不满足,则返回“NaN”。
- parseInt()函数
- parseInt()函数用于解析一个字符串,并返回指定的基数对应的整数值。
- 语法格式
- parseInt(string,radix);
- 其中string表示要被解析的值,如果该参数不是一个字符串,那么会使用toString()函数将其转换成字符串,而字符串前面的空白符会被忽略。
- radix表示的是进制转换的基数,数据范围是2~36,可以是使用频率比较高的二进制、十进制、八进制和十六进制等,默认值为10。因为对相同的数采用不同进制进行处理时可能会得到不同的结果,所以在任何情况下使用parseInt()函数时,建议都手动补充第二个表示基数的参数。
- parseInt()函数会返回字符串解析后的整数值,如果该字符串无法转换成Number类型,则会返回“NaN”。
- 在使用parseInt()函数将字符串转换成整数时,需要注意以下5点。(没怎么看)
- 非字符串类型转换为字符串类型(先转化为字符串)
- 数据截取的前置匹配原则(截取满足条件的值,不满足条件的舍弃)
- 对包含字符e的不同数据的处理差异
- 对浮点型数的处理
- map()函数与parseInt()函数的隐形坑
- parseFloat()函数
- 总结
- Number()函数转换的是传入的整个值,并不是像parseInt()函数和parseFloat()函数一样会从首位开始匹配符合条件的值。如果整个值不能被完整转换,则会返回“NaN”。
- parseFloat()函数在解析小数点时,会将第一个小数点当作有效字符,而parseInt()函数在解析时如果遇到小数点会直接停止,因为小数点不是整数的一部分。
- parseFloat()函数在解析小数点时,会将第一个小数点当作有效字符,而parseInt()函数在解析时如果遇到小数点会直接停止,因为小数点不是整数的一部分。
- Number()函数可以用于将任何类型转换为Number类型,它在转换时遵循下列规则。
- isNaN()函数与Number.isNaN()函数对比
- isNaN()函数
- 首先我们来看看isNaN()函数的作用,它用来确定一个变量是不是NaN。NaN是一个Number类型的数值,只不过这个值无法用真实的数字表示.
- Number.isNaN()函数
- 既然在全局环境中有isNaN()函数,为什么在ES6中会专门针对Number类型增加一个isNaN()函数呢?这是因为isNaN()函数本身存在误导性,而ES6中的Number.isNaN()函数会在真正意义上去判断变量是否为NaN,不会做数据类型转换。只有在传入的值为NaN时,才会返回“true”,传入其他任何类型的值时会返回“false”。
- 总结
- isNaN()函数与Number.isNaN()函数的差别如下。
- isNaN()函数在判断是否为NaN时,需要先进行数据类型转换,只有在无法转换为数字时才会返回“true”;
- Number.isNaN()函数在判断是否为NaN时,只需要判断传入的值是否为NaN,并不会进行数据类型转换。
- isNaN()函数与Number.isNaN()函数的差别如下。
- isNaN()函数
- 浮点型运算
- 存在 0.1 + 0.2 = 0.30000000000000004 的问题
- 获取多个数据中的最大的乘数因子,再进行运算
- 类型介绍
- String 类型
- 在将某个数据转换为字符串时,有一个简单的方法是直接使用加号(+)拼接一个空字符串(””)。
- 字符串字面量
- 直接调用String()函数
- 直接调用String()函数,会将传入的任何类型的值转换成字符串类型,在转换时遵循的规则如下
- 如果是Number类型的值,则直接转换成对应的字符串。
- 如果是Boolean类型的值,则直接转换成’true’或者’false’。
- 如果值为null,则返回字符串’null’;
- 如果值为undefined,则返回字符串’undefined’;
- 如果值为字符串,则直接返回字符串本身;
- 如果值为引用类型,则会先调用toString()函数获取返回值,将返回值按照上述步骤①~⑤判断能否转换字符串类型,如果都不满足,则会调用对象的valueOf()函数获取返回值,并将返回值重新按照步骤①~⑤判断能否转换成字符串类型,如果也不满足,则会抛出类型转换的异常。
- new String()构造函数
- new String()构造函数使用new运算符生成String类型的实例,对于传入的参数同样采用和上述String()函数一样的类型转换策略,最后的返回值是一个String类型对象的实例。
- 三者在作比较时的区别
- 使用第一种字符串字面量方式和第二种直接调用String()函数的方式得到的字符串都是基本字符串,而通过第三种方式,new运算符生成的字符串是字符串对象。
- 直接调用String()函数,会将传入的任何类型的值转换成字符串类型,在转换时遵循的规则如下
- 函数的调用
- 在String对象的原型链上有一系列的函数,例如indexOf()函数、substring()函数、slice()函数等,通过String对象的实例可以调用这些函数做字符串的处理。但是我们发现,采用字面量方式定义的字符串没有通过new运算符生成String对象的实例也能够直接调用原型链上的函数。
- 实际上基本字符串本身是没有字符串对象的函数,而在基本字符串调用字符串对象才有的函数时,JavaScript会自动将基本字符串转换为字符串对象,形成一种包装类型,这样基本字符串就可以正常调用字符串对象的方法了。
- 基本字符串和字符串对象在经过eval()函数处理时,会产生不同的结果。eval()函数会将基本字符串作为源代码处理,如果涉及表达式会直接进行运算,返回运算后的结果;而字符串对象则会被看作对象处理,返回对象本身。
- 运算符
- 等于运算符
- 双等于运算符在比较时,会将两端的变量进行隐式类型转换,然后比较值的大小。
- 三等于运算符在比较时,会优先比较数据类型,数据类型相同才去判断值的大小,如果类型不同则直接返回“false”。
- 三等于运算符
- 如果比较的值类型不相同,则直接返回“false”。
- 如果比较的值都是数值类型,则直接比较值的大小,相等则返回“true”,否则返回“false”。需要注意的是,如果参与比较的值中有任何一方为NaN,则返回“false”。
- 如果比较的值都是字符串类型,则判断每个位置的字符是否一样,如果一样则返回“true”,否则返回“false”。
- 如果比较的值都是Boolean类型,则两者同时为true或者false时,返回“true”,否则返回“false”。
- 如果比较的值都是null或者undefined,则返回“true”;如果只有一方为null或者undefined,则返回“false”。
- 如果比较的值都是引用类型,则比较的是引用类型的地址,当两个引用指向同一个地址时,则返回“true”,否则返回“false”。
- 双等于运算符
- 如果比较的值类型相同,则采用与三等于运算符一样的规则。
- 如果比较的值类型不同,则会按照下面的规则进行转换后再进行比较。
- 如果比较的一方是null或者undefined,只有在另一方是null或者undefined的情况下才返回“true”,否则返回“false”。
- 如果比较的是字符串和数值类型数据,则会将字符串转换为数值后再进行比较,如果转换后的数值相等则返回“true”,否则返回“false”。
- 需要注意的是,如果字符串是十六进制的数据,会转换为十进制后再进行比较。
- 字符串并不支持八进制的数据,如果字符串以0开头,则0会直接省略,后面的值当作十进制返回。
- 如果其中一个值是对象类型,另一个值是基本数据类型或者对象类型,则会调用对象的valueOf()函数或者toString()函数,将其转换成基本数据类型后再作比较,关于valueOf()函数和toString()函数会在1.5节中详细讲到。
- typeof运算符
- 括号有的时候是必须的,如果不加上括号将会因为优先级的问题得不到我们想要的结果。
- 处理Boolean类型的值
- Boolean类型的值只有两个,分别是true和false。typeof运算符在处理这两个值以及它们的包装类型时都会返回“boolean”,但是不推荐使用包装类型的写法。
- 处理Number类型的值
- 对于Number类型的数据,可以概括为以下这些值,typeof运算符在处理时会返回“number”。· 数字,如1、123、145。
- Number类型的静态变量,如Number.MAX_VALUE、Number.EPSILON等。
- Math对象的静态变量值,如Math.PI、Math.LN2(以e为底,2的对数)。
- NaN,虽然NaN是Not a Number的缩写,但它是Number类型的值。
- Infinity和-Infinity,表示的是无穷大和无穷小的数。
- 数值类型的包装类型,如Number(1)、Number(123),虽然它们也会返回“number”,但是并不推荐这么写。
- 处理String类型的值
- 对于String类型的数据,可以概括为以下这些值,typeof运算符在处理时会返回“string”。
- 任何类型的字符串,包括空字符串和非空字符串。
- 返回值为字符串类型的表达式。
- 字符串类型的包装类型,例如String(‘hello’)、String(‘hello’ +’world’),虽然它们也会返回“String”,但是并不推荐这么写。
- 处理Symbol类型的值
- Symbol类型是在ES6中新增的原生数据类型,表示一个独一无二的值,typeof运算符处理后得到的返回值为“symbol”
- 处理Function类型的值
- 对于Function类型的数据,可以概括为以下这些值,typeof运算符在处理时会返回“function”。
- 函数的定义,包括函数声明或者函数表达式两种形式。
- 使用class关键字定义的类,class是在ES6中新增的关键字,它不是一个全新的概念,原理依旧是原型继承,本质上仍然是一个Function。
- 某些内置对象的特定函数,例如Math.sin()函数、Number.isNaN()函数等。
- Function类型对象的实例,一般通过new关键字得到。
- 处理Object类型的值
- 对于Object类型的数据,可以概括为以下这些值,typeof运算符在处理时会返回“object”。
- 对象字面量形式,例如{name: ‘kingx’}。
- 数组,例如[1, 2, 3]和Array(1, 2, 3)。
- 所有构造函数通过new操作符实例化后得到的对象,例如newDate()、new function(){},但是new Function(){}除外。
- 通过new操作符得到的基本数据类型的包装类型对象,如newBoolean(true)、newNumber(1),但不推荐这么写。
- 细心的读者可能发现了,与基本数据类型的包装类型相关的部分,我们都有写“不推荐这么写”,这是为什么呢?因为涉及包装类型时,使用了new操作符与没有使用new操作符得到的值在通过typeof运算符处理后得到的结果是不一样的,很容易让人混淆。
- typeof运算符区分对待Object类型和Function类型
- 在Nicholas C.Zakas所著的《JavaScript高级程序设计》一书中讲到,从技术角度讲,函数在ECMAScript中是对象,不是一种数据类型。然而,函数也确实有一些特殊的属性,因此通过typeof运算符来区分函数和其他对象是有必要的。另外,在实际使用过程中,有必要区分Object类型和Function类型,而typeof运算符就能帮我们实现。
- 处理Undefined类型的值
- 虽然Undefined类型的值只有一个undefined,但是typeof运算符在处理以下3种值时都会返回“undefined”。
- undefined本身。
- 未声明的变量。
- 已声明未初始化的变量。
- typeof运算符对null的处理使用typeof运算符对null进行处理,返回的是“object”,
- 这是一个让大家都感到惊讶的结果。因为null是一个原生类型的数据,为什么typeof运算符会返回“object”呢?
- 这是一个在JavaScript设计之初就存在的问题,这里简单介绍下。
- 在JavaScript中,每种数据类型都会使用3bit表示。· 000表示Object类型的数据。· 001表示Int类型的数据。
- · 010表示Double类型的数据。
- · 100表示String类型的数据。
- · 110表示Boolean类型的数据。
- 由于null代表的是空指针,大多数平台中值为0x00,因此null的类型标签就成了0,所以使用typeof运算符时会判断为object类型,返回“object”。虽然在后面的提案中有提出修复方案,但是因为影响面太大,所以并没有被采纳,从而导致这个问题一直存在。
- 虽然Undefined类型的值只有一个undefined,但是typeof运算符在处理以下3种值时都会返回“undefined”。
- typeof运算符相关语法的括号在前文中有讲到,括号有时是必须存在的,如果不加上括号则会因为优先级的问题得不到我们想要的结果。
- 逗号运算符
- 逗号作为运算符的表现形式为:表达式1,表达式2,表达式3,……,表达式n。
- 在for循环中批量执行表达式
- 用于交换变量,无须额外变量
- 用于简化代码
- 用小括号保证逗号运算符的优先级
- 运算符优先级
- toString()函数与valueOf()函数
- 在JavaScript中,toString()函数与valueOf()函数解决的是值的显示和运算的问题,所有引用类型都拥有这两个函数。
- toString()函数的作用是把一个逻辑值转换为字符串,并返回结果。Object类型数据的toString()函数默认的返回结果是”[object Object]”,当我们自定义新的类时,可以重写toString()函数,返回可读性更高的结果。在JavaScript中,Array,Function,Date等类型都实现了自定义的toString()函数。
- Array的toString()函数返回值为以逗号分隔构成的数组成员字符串,例如[1, 2,3].toString()结果为字符串’1,2,3’。
- Function的toString()函数返回值为函数的文本定义,例如(function(x){return x 2;}).toString()的结果为字符串”function(x){return x 2;}”。
- Date的toString()函数返回值为具有可读性的时间字符串,例如,new Date().toString()的结果为字符串”Sun Nov 25 201815:00:16 GMT+0800 (中国标准时间)”。
- valueOf()函数
- valueOf()函数的作用是返回最适合引用类型的原始值,如果没有原始值,则会返回引用类型自身。Object类型数据的valueOf()函数默认的返回结果是”{}”,即一个空的对象字面量。对于Array、Function、Date等类型,valueOf()函数的返回值是什么呢?
- Array的valueOf()函数返回的是数组本身,例如[1, 2,3].valueOf()返回的结果为“[1,2,3]”。
- function的valueOf()函数返回的是函数本身,例如(function(x){return x 2;}).valueOf()返回的结果为函数本身“function(x){return x 2;}”。
- Date的valueOf()函数返回的是指定日期的时间戳,例如newDate().valueOf()返回的结果为“1543130166771”。
- 如果一个引用类型的值既存在toString()函数又存在valueOf()函数,那么在做隐式转换时,会调用哪个函数呢?这里我们可以概括成两种场景,分别是引用类型转换为String类型,以及引用类型转换为Number类型。
- 引用类型转换为String类型一个引用类型的数据在转换为String类型时,一般是用于数据展示,转换时遵循以下规则。
- 如果对象具有toString()函数,则会优先调用toString()函数。如果它返回的是一个原始值,则会直接将这个原始值转换为字符串表示,并返回该字符串。
- 如果对象没有toString()函数,或者toString()函数返回的不是一个原始值,则会再去调用valueOf()函数,如果valueOf()函数返回的结果是一个原始值,则会将这个结果转换为字符串表示,并返回该字符串。
- 如果通过toString()函数或者valueOf()函数都无法获得一个原始值,则会直接抛出类型转换异常。
- 引用类型转换为Number类型一个引用类型的数据在转换为Number类型时,一般是用于数据运算,转换时遵循以下规则。
- 如果对象具有valueOf()函数,则会优先调用valueOf()函数,如果valueOf()函数返回一个原始值,则会直接将这个原始值转换为数字表示,并返回该数字。
- 如果对象没有valueOf()函数,或者valueOf()函数返回的不是原生数据类型,则会再去调用toString()函数,如果toString()函数返回的结果是一个原始值,则会将这个结果转换为数字表示,并返回该数字。
- 如果通过toString()函数或者valueOf()函数都无法获得一个原始值,则会直接抛出类型转换异常
- JavaScript中常用的判空方法
- 判断变量为空对象
- 判断变量为null或者undefined
- 判断变量为空对象{}
- 判断变量为空数组
- 判断变量为空字符串
- 判断变量为0或者NaN
- 判断变量为0或者NaN
- !x == true的所有情况
- 变量为null。
- 变量为undefined。
- 变量为空字符串’ ‘。
- 变量为数字0,包括+0、-0。
- 变量为NaN。
- 判断变量为空对象
- JavaScript中的switch语句
- 严格相等
- 在JavaScript中,switch语句可以用来判断任何类型的值,不一定是Number类型。
- 等于运算符