美文网首页
Javascript学习笔记-强制类型转换

Javascript学习笔记-强制类型转换

作者: Patrick浩 | 来源:发表于2017-09-16 12:14 被阅读0次
Javascript类型转换.png

1. 基本类型转换

由于Javascript中存在七种基本类型:number, string , boolean , object, null, undefined, symbol,在使用过程中会有意识和无意识的在 运行时 存在相互转换。

1.1 toString

1.1.1 较大数和较小数

当数字处于较大或较小时,由于Javascript会将数字转换为科学记数法方式记录,这个时候如果对其进行转换为字符串,那么显示结果是科学记数法的字符串

console.log(String(0.0000000001)); // '1e-10'
console.log(String(10000000000000000000000)); // '1e+22'
1.1.2 对象的toString

一般对象的toString方法,将会显示该对象的[[class]]

Object.prototype.toString.call({}); // '[object Object]'
Object.prototype.toString.call(function(){}) // '[object Function]'
1.1.3 数组的toString

数组由于自身重写过toString方法,数组的toString方法会返回逗号连接的字符串

Array.prototype.toString.call(['1', 'a', {'a': 1}]); // '1,a,[object Object]'
1.1.4 JSON.stringify()

JSON.stringify()方法用于将数据转换为JSON格式的字符串,但是对于undefined, function, symbol类型的数据,在转换时会选择抛弃,从而返回undefined

JSON.stringify(undefined); // undefined
JSON.stringify(function(){}); // undefined
JSON.stringify(Symbol('test')); // undefined

转换对象在数组中时,这些值会被赋值为null

JSON.stringify([undefined, 1, function(){}]); // [null, 1, null]    

如果转换对象出现循环引用,那么在转换的时候会抛出异常。
为了使得我们所有的对象在转换成JSON字符串的时候可以正常转换,我们可以定义toJSON方法,该方法在JSON.stringify调用前会进行调用,对数据进行处理

var a = {a: 1, b: 2};
a.toJSON = function() {
    return {a: 1}
}
JSON.stringify(a); // "{"a": "1"}"

JSON.stringify一共可以接受三个参数,除了第一个参数为转换对象以外,第二个参数可以接收了一个数组或者方法对转换对象属性进行过滤,第三个参数则可以将JSON字符串进行格式化

var a = {a: 1, b: 2};
// 第二个参数使用数组进行过滤
JSON.stringify(a, ['a']); // "{"a": "1"}"
// 第二个参数使用function,自身对象会先调用方法一次后,每个属性调用一次,返回undefined时则过滤掉该属性
JSON.stringify(a, (k, v)=>{
    if (k!=='a') {
      return v;
    }
}); // "{"b": 2}"
// 第三个参数进行格式化,接收数字时每个层级添加相应数目空格
JSON.stringify({a:1, b:2, c: {a: 1}}, null, 2);
// 第三个参数如果为字符串,则每个层级添加该字符串,能添加的字符串最大长度为10
JSON.stringify({a:1, b:2, c: {a: 1}}, null, '--');

1.2 toNumber

1.2.1 基本类型转Number

基本类型转为number,按照以下规则转换:

// null , false , '' 转换为0
console.log(Number(null)); // 0
console.log(Number(false)); // 0
console.log(Number('')); // 0
// true转换为1
console.log(Number(true)); // 1
// undefined转换为NaN 
console.log(Number(undefined)); // NaN
// 字符串如果是数字格式则会进行转换
console.log(Number('123')); // 123
1.2.2 对象转Number

遵循toPrimitive的规则,如果对象存在valueOf方法,则调用该方法,如果调用后返回的结果为基本类型,则按照 1.2.1 基本类型转Number 规则进行转换;如果返回不为基本类型或者不存在valueOf方法,则调用toString方法后,按照 1.2.1 基本类型转换Number 规则进行处理

var a = [1]; 
// 转为Number,首先使用a.valueOf()方法,返回[1] 
// 继续调用toString方法,返回'1' 
// 再将字符串转为数字1
console.log(Number(a)); // 1
// 如果重写valueOf方法,则会返回超乎想象的结果
a.valueOf = () => {return 2};
console.log(Number(a)); // 2

1.3 toBoolean

boolean类型转换过程只会进行真假值的检查,其中假值包括: false, '', null, undefined, NaN, +0, -0,假值将会转换为false,假值以外的其他值均为真值,转换为true

console.log(Boolean(false)); // false
console.log(Boolean('')); // false
console.log(Boolean(null)); // false
console.log(Boolean(undefined)); // false
console.log(Boolean(NaN)); // false
console.log(Boolean(+0)); // false
console.log(Boolean(-0)); // false

1.4 特殊

对于一个特殊的对象Object.create(null),由于原型链的继承关系,该对象不继承Object,所以不存在valueOftoString方法,那么在进行转换的时候将抛出异常

var a = Object.create(null);
console.log(Number(a)); // Uncaught TypeError: Cannot convert object to primitive value

2. 类型转换

类型转换可以分为显示类型转换和隐式类型转换,但显示和隐式只是相对的,在我们知道会进行转换的时候他就是隐式,当我们知道会进行转换以后其实就变为了显式转换了。

2.1 显示类型转换

2.1.1 String()和Number()转换

按照 1. 基本类型转换 的toString和toNumber的规则进行转换

2.1.2 一元运算符转换

使用一元运算符(+, -)会将数据转换为number类型,相当于Number(data)

console.log(+[]); // 0 ,使用toNumber的规则,相当于Number([])
2.1.3 位反运算符转换

使用位反运算符(~)会将数据转换为number类型,相当于-(Number(data) + 1)

console.log(~[]); // -1

利用位反运算符,可以一些特定方法返回值进行处理后,简化判断

// 例如indexOf匹配失败会返回-1,就可以利用位反运算简化判断条件
if('abc'.indexOf('a') > -1) {}
// 相当于
if(~'abc'.indexOf('a')){}
2.1.4 字符串解析

使用parseIntparseFloat可以将字符串(非字符串会优先转换为字符串)解析为number类型,不同于Number()的强制类型转换,解析过程会进行到不能解析为止,而Number()转换在判断不能转换到时候直接返回NaN

console.log(parseInt('12ab')); // 12
console.log(Number('12ab')); // NaN

在ES5以后,parseInt默认使用了10进制作为基数进行转换,可以通过第二个参数指定基数,此时对字符串解析过程会按照指定进制进行

console.log(parseInt('1a', 19)); // 29 因为按照19进制1和a都是有效的字符,返回结果为29
2.1.5 !转换

使用'!',可以转换为boolean类型,转换相当于Boolean(data)

console.log(!0); // true
console.log(!!0); //false
2.1.6 Symbol()对象转换

Symbol对象不能通过隐式转换进行,如果要进行转换必须使用构造方法来显示转换(似乎只能转为字符串)。

var a = Symbol('1');
console.log(a + 1); Uncaught TypeError: Cannot convert a Symbol value to a number
console.log(String(a) + 1); // 'Symbol(1)1'

2.2 隐式类型转换

2.2.1 算数运算转换

在算数运算的过程中会进行数据转换:
对于+运算来说,如果两个操作数中存在字符串,则会尝试进行字符串连接操作,如果操作数为对象,则会使用toPrimitive(使用valueOf方法和toString方法)转为基本类型后,再进行判断。如果不存在字符串,则全部转为数字进行加法操作。

console.log(1 + ['1']); // 11 , 先将对象['1']根据toPrimitive规则转为'1',操作变为 1 + '1' , 进行字符串拼接

对于-运算来说,直接将所有操作数进行toNumber操作后进行计算

console.log(1 - ['1']); // 0
2.2.2 逻辑语句中的类型转换

作为逻辑语句中的判断条件,将转换为boolean值进行处理

if(1) { console.log(1)}; //  由于Boolean(1)是true,所以会打印1
if(0) { console.log(1)}; //  由于Boolean(0)是false,所以不会打印1
2.2.3 ||和&&

||&&的操作,返回结果并不是boolean值,而是根据短路规则,判断操作数的Boolean()结果,返回两个操作数的其中之一,其中||true时进行短路返回,&&false时进行短路返回

var a = 1 && 0;
console.log(a); // 0 , 由于第一个操作数Boolean(1)是true,所以返回第二个操作数
a = 0 && 1; 
console.log(a); // 0 , 由于第一个操作数Boolean(0)是false,所以返回第一个操作数
a = 1 || 0; 
console.log(a); // 1, 由于第一个操作数Boolean(1)是true,所以返回第一个操作数
a = 0 || 1; 
console.log(a); // 1, 由于第一个操作数Boolean(0)是false,所以返回第二个操作数

3. 数据比较

3.1 宽松等于

使用==进行比较的称做宽松等于,区别于===的严格等于,在于进行比较的时候,等式两边的数值在类型不相等的时候会尝试进行强制转换,而严格等于不会进行类型的转换。
宽松等于的转化规则如下:

  • 如果两个比较数类型一致且为基本类型,则直接进行比较,数字按照大小,字符串按照字母表顺序比较。
  • 如果两个比较数类型不一致且为基本类型,则转换为number进行比较。
  • 如果两个比较数据均为对象类型,则比较对象的引用是否相等
  • 如果两个数据中一个为对象,则根据toPrimitive规则,将其转换为基本类型后,进行比较。

console.log('a' == 'a'); // true , 类型相同且为基本类型,则直接比较
console.log('1' == 1); // true , 类型不同但均为基本类型,将'1'转为number进行比较
console.log({} == {}); // false , 两个比较数均为对象,判断引用是否相等
console.log('a' == ['a']); // true,一个比较数为对象,则将['a']转换为'a'后进行比较

对于特殊的undefinednull

console.log(undefined == null); // true

3.2 抽象比较

抽象比较也就是非等于比较,比较规则和宽松等于规则相同

console.log('a' < 'b'); // true, 类型相同,直接进行比较,字符串按照字母表顺序
console.log('0' < 1); // true, 类型不同但均未基本类型,将'0'转为number后进行比较
console.log('a' < ['b']); // true, 一个比较数为对象,则将['b']转换为'b'后进行比较

4. 参考

《你不知道的Javascript(中卷)》

相关文章

  • Javascript学习笔记-强制类型转换

    1. 基本类型转换 由于Javascript中存在七种基本类型:number, string , boolean ...

  • JavaScript的强制类型转换

    强制类型转换 将javascript的值从一种类型转换为另一种类型的值——>类型转换隐式类型转换——>强制类型转换...

  • ToBoolean 转换布尔值

    JavaScript中,抽象值操作ToBoolean用于将数据类型强制转换为布尔类型 以下数据值在强制类型转换为b...

  • javascript强制类型转换

    javascript强制类型转换 一、转换为数值类型 Number(参数) 把任何类型转换为数值类型A.如果是布尔...

  • JavaScript学习笔记三

    JavaScript学习笔记三 个人学习笔记参考阮一峰的JavaScript教学类型转换,内存,深拷贝,关于内存的...

  • JavaScript 数值转换

    JavaScript 数值转换 JavaScript 字符串转换数字方法主要有四种:强制类型转换、转换函数、利用J...

  • Javascript 强制类型转换

    JS中的数据类型:1.值类型(基本类型):字符串(String)、数字(Number)、布尔(Boolean)、对...

  • JavaScript 强制类型转换

    前言 关于强制类型转换是一个设计上的缺陷还是有用的特性,这一争论从JavaScript 诞生之日起就开始了。在很多...

  • 前端常见面试题(十三)@郝晨光

    列举三种强制类型转换和两种隐式类型转换 JavaScript是一门弱类型语言,在JavaScript中声明变量不需...

  • 2018-06-13

    JS类型转换(强制和自动的规则) 显式转换 通过手动进行类型转换,Javascript提供了以下转型函数: 转换为...

网友评论

      本文标题:Javascript学习笔记-强制类型转换

      本文链接:https://www.haomeiwen.com/subject/khcgjxtx.html