JS中的类型转化(强制类型转换与隐式类型转换)

文章思维导图
JS中的类型转化(强制类型转换与隐式类型转换)_第1张图片

文章思维导图获取 点击

目录

  • 1 类型之间的转化
    • 1.1 基本类型
    • 1.2 引用类型
  • 2 强制类型转换
    • 2.1 `parseInt()`:解析一个字符串,并返回一个**整数**
    • 2.2` parseFloat()`:可解析一个字符串,并返回一个浮点数
    • 2.3 `Number();`
    • 2.4 `String()`
    • 2.5 `Boolean()`
  • 3 隐式类型转换
    • 3.1 加号
    • 3.2 减号、乘号、除号
    • 3.3 关系运算符
      • 3.3.1 `==`
        • 特殊性
        • 其他数据类型
        • 对于NaN的精确判断
          • `isNaN`的不准确性
          • 精确的判定NaN的值
      • 3.3.2 `< >`
        • 一般情况
        • 字符串的特殊性
    • 3.4 逻辑运算符 !
    • 3.5 复杂数据类型
      • 3.5.1 valueOf方法重写

1 类型之间的转化


1.1 基本类型


字符串 数值 布尔值
字符串 Nan(非数字性字符串)/数值 空字符串:false,其他:true
数值 相应的字符串 0:false,其他:true
布尔值 "true"/"false" true=>1/false=>0
undefined "undefined" NaN false
null "null" 0 false

1.2 引用类型


数字 布尔值
对象 NaN 空对象=>false,其他=>true
数组 空数组=>0,其他=>NaN 空数组=>false,其他=>true

2 强制类型转换


以下的数据类型转换都属于全局函数

2.1 parseInt():解析一个字符串,并返回一个整数

  • 第一个参数:要解析的字符串
    • 非数字返回NaN
  • 第二个参数:以多少进制解析字符串
  • 不传递第二个参数,以字符串本身来解析
    • 1-9 开头的数字以十进制解析
    • 0x 开头以十六进制解析
    • ️0 开头八进制或者十六进制
parseInt("10");			//返回 10
parseInt("19",10);		//返回 19 (10+9)
parseInt("11",2);		//返回 3 (2+1)
parseInt("17",8);		//返回 15 (8+7)
parseInt("1f",16);		//返回 31 (16+15)
parseInt("010");		//未定:返回 10 或 8

2.2parseFloat():可解析一个字符串,并返回一个浮点数

+ 只有一个参数,传递字符串
+ 规则与`parseInt`相同
parseFloat("10")        //10
parseFloat("10.00")     //10
parseFloat("10.33")     //10.33
parseFloat("34 45 66")  //34
parseFloat(" 60 ")      //60
parseFloat("40 years")  //40
parseFloat("He was 40") //NaN

2.3 Number();

var test1 = new Boolean(true);
var test2 = new Boolean(false);
var test3 = new Date();
var test4 = new String("999");
var test5 = new String("999 888");

console.log(Number(test1));/* 将布尔值转化为数字 */
console.log(Number(test2));
console.log(Number(test3));/* 将日期转化为数字,变为毫秒数 */
console.log(Number(test4));/* 字符串为数字,转化为数字 */
console.log(Number(test5));/* 字符串含有非数字的符号,返回NaN */

输出

 1
 0
 1593869544742
 999
 NaN

2.4 String()

var test1 = new Boolean(1);
var test2 = new Boolean(0);
var test3 = new Boolean(true);
var test4 = new Boolean(false);
var test5 = new Date();
var test6 = new String("999 888");
var test7 = 12345;

console.log(String(test1));//true
console.log(String(test2));//false
console.log(String(test3));//true
console.log(String(test4));//false
console.log(String(test5));//Wed Oct 28 00:17:40 UTC+0800 2009
console.log(String(test6));//999 888
console.log(String(test7));//12345

2.5 Boolean()


  • 使用Boolean一下会返回false
    1. 0
    2. -0
    3. null
    4. “”
    5. false
    6. undefined
    7. NaN
  • 其他都会转化为true,即使是'false'

3 隐式类型转换


隐式类型转化主要通过一些运算符,如:+、-、*、==

3.1 加号


  1. 先判断+两端是否有字符串,如果有字符串,将其他类型转化为字符串然后拼接
  2. 如果没有字符串,转化为数值之后,进行运算
console.log('hello world' + 123)//hello world123
console.log('hello world' + false)//hello worldfalse
console.log('hello world' + null)//hello worldnull
console.log('hello world' + undefined)//hello worldundefined
console.log(123 + false)//123
console.log(null + undefined)//NaN

3.2 减号、乘号、除号


number与其他数据类型进行减法运算的时候,会优先把其他数据类型转化为number然后进行运算

最终的结果一定是数字(包括NaN、Infinity)

// 加法
console.log(4 - 'hello')// NaN
console.log(4 - '123')//-119
console.log(4 - true)//3
console.log(4 - null)//4
console.log(4 - undefined)//NaN
// 乘法
console.log(4 * 'hello')// NaN
console.log(4 * '123')//492
console.log(4 * true)//4
console.log(4 * null)//0
console.log(4 * undefined)//NaN
// 除法
console.log(4 / 'hello')// NaN
console.log(4 / '123')//0.032520325203252036
console.log(4 / true)//4
console.log(4 / null)//Infinity
console.log(4 / undefined)//NaN

3.3 关系运算符


这里的关系运算符包括==/>/<

3.3.1 ==

特殊性


两个特殊性

undefined==null //返回true
NaN==NaN //返回false

其他数据类型


string、boolean:转化为数字(调用Number())之后进行比较

'0'== false //true

对于NaN的精确判断


isNaN的不准确性

isNaN("foo"); // true
isNaN(undefined); // true
isNaN({}); // true
isNaN({ valueOf: "foo" }); // true

无论是对象还是空对象,一律判定为 true

精确的判定NaN的值

可以利用NaN本身不相等来初始化一个函数

NaN == NaN // false
NaN !== NaN  // true
const obj = {name:'SunWuKong'}
obj !== obj // false

初始化函数

function isReallyNaN(element) {
    return element !== element;
}

只要传入元素就能判断他是否为NaN

3.3.2 < >


一般情况

一般情况下,会先将相应的数据类型转化为数字,在进行比较

1 > false // ture
null > -1 // true

字符串的特殊性

  1. 比较的两位数据中有一个是字符串
    • 将字符串转化为数字,再进行进行比较
"10" > 2 // ture
  1. 比较的两位数据中都是字符串
"10" > "2" // false

如果比较的两位数据中都是字符串,他会叫字符串转化为unicode编码,再进行比较

  • 通过charCodeAt()可以得到字符串对应的unicode编码 点击
"10".charCodeAt() // 49
"2".charCodeAt() // 50
// 所以 "10"<"2"
  1. 长度不相等的字符串的比较
    • 从左向右以此比较字母的unicode,如果相同则比较下一位,知道返回结果。
 console.log("abc" > "d") // false
 console.log("abc".charCodeAt())//97
 console.log("d".charCodeAt())//100
  • 他会先将adunicode编码进行比较,d的编码大于a直接得出结果

3.4 逻辑运算符 !

相当于Boolean(),他会把后边的类型转化为布尔值,转化的类型请参见Boolean全局函数

3.5 复杂数据类型

复杂的数据类型,比如说对象,比如说数组。一般会先调用valueOf()方法,之后在调用toString()方法

举例

console.log([1,2] == '1,2') // true
  • 经历了上面的隐式类型转换,我们知道,等号两边的数据类型是数值==,才能进行运算,所以会想尽一些办法把数组和字符串变成数值
  • 对于数组来说,是复杂的数据类型,会先调用valueOf方法,得到其原始值
  • 如果原始值不是number,则会调用toString()方法将其转化成字符串
  • 之后在调用Number()全局方法,将其转化为number
console.log([1,2].valueOf())//[1, 2]
console.log([1,2].toString())//1,2

3.5.1 valueOf方法重写

valueOftoString,都是允许被重写的,当两者都存在的时候,会优先调用valueOf,我们下面完成这样一个题

var a = ?
if (a == 1 && a==2 && a == 3) {
    console.log('you are right')
}
// 如何打印成 you are right?

我们进行这样的分析

  1. 题目是用的==,他会首先进行隐式类型转换,如果我们给a赋值成一个复杂的数据类型,比如对象,他进行类型转换的时候会首先调用方法valueOf()
  2. 因为要进行三次类型转换,他会调用三次valueOf方法,我们能不能通过重写valueOf()方法,实现呢?

实现

var a = {
   i:0,
   valueOf:function(){
       return ++a.i // 每一次调用a的值都会一次加1
   }
}
if (a == 1 && a==2 && a == 3) {
   console.log('you are right')
}

你可能感兴趣的:(ESMAScript)