JS类型转换(强制和自动的规则)
显式转换
通过手动进行类型转换,Javascript提供了以下转型函数:
转换为数值类型:
Number(mix)、parseInt(string,radix)、parseFloat(string)
转换为字符串类型:
toString(radix)、String(mix)
转换为布尔类型:
Boolean(mix)
Number转换
Number(mix)函数,可以将任意类型的参数mix转换为数值类型。其规则为:
(1)如果是布尔值,true和false分别被转换为1和0
(2)如果是数字值,返回本身。
(3)如果是null,返回0.
(4)如果是undefined,返回NaN。
(5)如果是字符串,遵循以下规则:
1、如果字符串中只包含数字,则将其转换为十进制(忽略前导0)
2、如果字符串中包含有效的浮点格式,将其转换为浮点数值(忽略前导0)
3、如果是空字符串,将其转换为0
4、如果字符串中包含非以上格式,则将其转换为NaN
(6)如果是对象,则调用对象的valueOf()方法,然后依据前面的规则转换返回的值。如果转换的结果是NaN,则调用对象的toString()方法,再次依照前面的规则转换返回的字符串值。
console.log(Number(false)) // 0
console.log(Number(-0)) // -0
console.log(Number(Infinity)) // Infinity
console.log(Number(null)) // 0
console.log(Number(undefined)) // NaN
console.log(Number(0x11)) // 17
console.log(Number('03 ')) // 3
console.log(Number(' 03x')) // NaN
console.log(Number('0x03')) // 3
console.log(Number(' +0 ')) // 0
console.log(Number('0 5')) // NaN
console.log(Number('0a3')) // NaN
console.log(Number(' 0.3')) // 0.3
console.log(Number('0.3.2 ')) // NaN
console.log(Number('null')) // NaN
console.log(Number('')) // 0
console.log(Number(new Number(3))) // 3
console.log(Number(new String('null'))) // NaN
console.log(Number({a: 3})) // NaN
console.log(Number({})) // NaN
console.log(Number([3, 4])) // NaN
console.log(Number([])) // 0
console.log(Number([1])) // 1
console.log(Number(['333'])) // 333
下表列出了对象的valueOf()的返回值:
toString(radix)方法。除undefined和null之外的所有类型的值都具有toString()方法,其作用是返回对象的字符串表示。
String(mix)函数,将任何类型的值转换为字符串,其规则为:
(1)如果有toString()方法,则调用该方法(不传递radix参数)并返回结果
(2)如果是null,返回”null”
(3)如果是undefined,返回”undefined”
Bollean转换
Boolean(mix)函数,将任何类型的值转换为布尔值。
以下值会被转换为false:false、”"、0、+0、-0、NaN、null、undefined,其余任何值都会被转换为true。
parseFloat()
parseFloat() 方法可以把一个字符串解析成浮点数。该方法与Number.parseFloat() 函数相同。解析一个参数(必要时先转换为字符串)并返回一个浮点数。
返回值:给定值被解析成浮点数。如果给定值不能被转换成数值,则会返回NaN。
1、如果 parseFloat 在解析过程中遇到了正号(+)、负号(- U+002D HYPHEN-MINUS)、数字(0-9)、小数点(.)、或者科学记数法中的指数(e 或 E)以外的字符,则它会忽略该字符以及之后的所有字符,返回当前已经解析到的浮点数。
2、第二个小数点的出现也会使解析停止(在这之前的字符都会被解析)。
3、参数首位和末位的空白符会被忽略。
4、如果参数字符串的第一个字符不能被解析成为数字,则 parseFloat 返回 NaN。
5、parseFloat 也可以解析并返回 Infinity。
6、parseFloat解析 BigInt 为 Numbers, 丢失精度。因为末位 n 字符被丢弃。
7、parseFloat 也可以转换一个已经定义了 toString 或者 valueOf 方法的对象,它返回的值和在调用该方法的结果上调用 parseFloat 值相同。
// 下面的例子都返回3.14parseFloat(3.14)
parseFloat('3.14')
parseFloat(' 3.14 ')
parseFloat('314e-2')
parseFloat('0.0314E+2')
parseFloat('3.14some non-digit characters')
parseFloat({ toString: function() { return "3.14" } }); // 返回NaNparseFloat("FF2"); // 返回 900719925474099300,当整数太大以至于不能被转换时将失去精度。parseFloat(900719925474099267n)
parseFloat('900719925474099267n');
parseInt()
parseInt() 方法依据指定基数 [ 参数 radix 的值],把字符串 [ 参数 string 的值] 解析成整数。这个方法和Number.parseInt() 函数具有一样的函数功能。
Number.parseInt === parseInt; // true
语法:parseInt(string, radix)
string:要被解析的值。如果参数不是一个字符串,则将其转换为字符串(使用 ToString 抽象操作)。字符串开头的空白符将会被忽略。
radix:
-
一个介于2和36之间的整数(数学系统的基础),表示上述字符串的基数。比如参数 10 表示使用十进制数值系统。
-
始终指定此参数可以消除阅读该代码时的困惑并且保证转换结果可预测。当未指定基数时,不同的实现会产生不同的结果,通常认为其值默认为10
-
但是如果你的代码运行在过时的浏览器中,那么请在使用时总是显式地指定 radix。
-
在基数为 undefined,或者基数为 0 或者没有指定的情况下,JavaScript 作如下处理:
-
如果字符串 string 以"0x"或者"0X"开头, 则基数是16 (16进制).如果字符串 string 以"0"开头, 基数是8(八进制)或者10(十进制),那么具体是哪个基数由实现环境决定。ECMAScript 5 规定使用10,但是并不是所有的浏览器都遵循这个规定。因此,永远都要明确给出radix参数的值。
-
如果字符串 string 以其它任何值开头,则基数是10 (十进制)。
(1)忽略字符串前面的空格,直至找到第一个非空字符
(2)如果第一个字符不是数字符号或者负号,返回NaN
(3)如果第一个字符是数字,则继续解析直至字符串解析完毕或者遇到一个非数字符号为止
(4)如果上步解析的结果以0开头,则将其当作八进制来解析;如果以0x开头,则将其当作十六进制来解析
(5)如果指定radix参数,则以radix为基数进行解析
返回值:返回解析后的整数值。 如果被解析参数的第一个字符无法被转化成数值类型,则返回NaN。
一些数中可能包含e字符(例如6.022e23),使用parseInt去截取包含e字符数值部分会造成难以预料的结果。例如:
parseInt("6.022e23", 10); // 返回 6
parseInt(6.022e2, 10); // 返回 602
// 以下例子均返回15:
parseInt("0xF", 16);
parseInt("F", 16);
parseInt("17", 8);
parseInt(021, 8);
parseInt("015", 10); //
parseInt(015, 10); 返回 15
parseInt(15.99, 10);
parseInt("15,123", 10);
parseInt("FXX123", 16);
parseInt("1111", 2);
parseInt("15 * 3", 10);
parseInt("15e2", 10);
parseInt("15px", 10);
parseInt("12", 13); // 以下例子均返回 NaN:
parseInt("Hello", 8); // 根本就不是数值
parseInt("546", 2); // 除了“0、1”外,其它数字都不是有效二进制数字 // 以下例子均返回 -15:
parseInt("-F", 16);
parseInt("-0F", 16);
parseInt("-0XF", 16);
parseInt(-15.1, 10);
parseInt(" -17", 8);
parseInt(" -15", 10);
parseInt("-1111", 2);
parseInt("-15e1", 10);
parseInt("-12", 13); // 下例中全部返回 4:
parseInt(4.7, 10);
parseInt(4.7 * 1e22, 10); // 非常大的数值变成 4
parseInt(0.00000000000434, 10); // 非常小的数值变成 4 // 下面的例子返回 224
parseInt("0e0",16);
parseInt() // NaN
parseInt('') // NaN
隐式转换
在某些情况下,即使我们不提供显示转换,Javascript也会进行自动类型转换,主要情况有:
1、 用于检测是否为非数值的函数:isNaN(mix)
isNaN()函数,经测试发现,该函数会尝试将参数值用Number()进行转换,如果结果为“非数值”则返回true,否则返回false。
2、递增递减操作符(包括前置和后置 ++、--)、一元正负符号操作符(-、+)
这些操作符适用于任何数据类型的值,针对不同类型的值,该操作符遵循以下规则(经过对比发现,其规则与Number()规则基本相同):
(1)如果是包含有效数字字符的字符串,先将其转换为数字值(转换规则同Number()),在执行加减1的操作,字符串变量变为数值变量。
(2)如果是不包含有效数字字符的字符串,将变量的值设置为NaN,字符串变量变成数值变量。
(3)如果是布尔值false,先将其转换为0再执行加减1的操作,布尔值变量编程数值变量。
(4)如果是布尔值true,先将其转换为1再执行加减1的操作,布尔值变量变成数值变量。
(5)如果是浮点数值,执行加减1的操作。
(6)如果是对象,先调用对象的valueOf()方法,然后对该返回值应用前面的规则。如果结果是NaN,则调用toString()方法后再应用前面的规则。对象变量变成数值变量。
3、 加法运算操作符
加号运算操作符在Javascript也用于字符串连接符,所以加号操作符的规则分两种情况:
如果两个操作值都是数值,其规则为:
(1) 如果一个操作数为NaN,则结果为NaN
(2) 如果是Infinity+Infinity,结果是Infinity
(3) 如果是-Infinity+(-Infinity),结果是-Infinity
(4) 如果是Infinity+(-Infinity),结果是NaN
(5) 如果是+0+(+0),结果为+0
(6) 如果是(-0)+(-0),结果为-0
(7) 如果是(+0)+(-0),结果为+0
-
如果两个操作值都是字符串,则将它们拼接起来
-
如果只有一个操作值为字符串,则将另外操作值转换为字符串,然后拼接起来
-
如果一个操作数是对象、数值或者布尔值,则调用toString()方法取得字符串值,然后再应用前面的字符串规则。对于undefined和null,分别调用String()显式转换为字符串。
-
可以看出,加法运算中,如果有一个操作值为字符串类型,则将另一个操作值转换为字符串,最后连接起来。
console.log(1 + 'str') // '1str'console.log(1 + 3) // 4console.log(1 + '3') // '13'console.log('1' + '3') // '13'console.log(1 + []) // '1'console.log(1 + {}) // '1[object Object]'console.log(1 + function test(){}) // '1function test(){}'console.log([] + {}) // '[object Object]'console.log([1] + {}) // '1[object Object]'console.log([1] + [2]) // '12'console.log(['3'] + {}) // '3[object Object]'console.log(['4', '5'] + {}) // '4,5[object Object]'console.log(['4', '5'] + 1) // '4,51'console.log(['4', '5'] + '1') // '4,51'
4、 乘除、减号运算符、取模运算符
这些操作符针对的是运算,所以他们具有共同性:如果操作值之一不是数值,则被隐式调用Number()函数进行转换。
5、 逻辑操作符(!、&&、||)
逻辑非(!)操作符首先通过Boolean()函数将它的操作值转换为布尔值,然后求反。
一、逻辑与(&&)操作符,如果一个操作值不是布尔值时,遵循以下规则进行转换:
(1)如果第一个操作数经Boolean()转换后为true,则返回第二个操作值,否则返回第一个值(不是Boolean()转换后的值)
(2)如果有一个操作值为null,返回null
(3)如果有一个操作值为NaN,返回NaN
(4)如果有一个操作值为undefined,返回undefined
逻辑或(||)操作符,如果一个操作值不是布尔值,遵循以下规则:
(1)如果第一个操作值经Boolean()转换后为false,则返回第二个操作值,否则返回第一个操作值(不是Boolean()转换后的值)
(2)对于undefined、null和NaN的处理规则与逻辑与(&&)相同
6、 关系操作符(<, >, <=, >=)
与上述操作符一样,关系操作符的操作值也可以是任意类型的,所以使用非数值类型参与比较时也需要系统进行隐式类型转换:
(1)如果两个操作值都是数值,则进行数值比较
(2)如果两个操作值都是字符串,则比较字符串对应的字符编码值
(3)如果只有一个操作值是数值,则将另一个操作值转换为数值,进行数值比较
(4)如果一个操作数是对象,则调用valueOf()方法(如果对象没有valueOf()方法则调用toString()方法),得到的结果按照前面的规则执行比较
(5)如果一个操作值是布尔值,则将其转换为数值,再进行比较
注:NaN是非常特殊的值,它不和任何类型的值相等,包括它自己,同时它与任何类型的值比较大小时都返回false。
7、 相等操作符(==)
相等操作符会对操作值进行隐式转换后进行比较:
(1)布尔类型与其它任何类型进行比较,布尔类型将会转换为number类型,如果为true,那么会转换为1,如果为false,会转换为整数0,即0。
(2)如果一个操作值为字符串,另一个操作值为数值,则通过Number()函数将字符串转换为数值
(3)如果一个操作值是对象,另一个不是,则调用对象的valueOf()方法,得到的结果按照前面的规则进行比较
(4)null与undefined是相等的
(5)如果一个操作值为NaN,则相等比较返回false
(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象
(7)number类型或string类型与object类型进行比较,number或者string类型都会转换为object类型
Error对象
当代码运行时的发生错误,会创建新的Error
对象,并将其抛出。
通过Error的构造器可以创建一个错误对象。当运行时错误产生时,Error的实例对象会被抛出。Error对象也可用于用户自定义的异常的基础对象。下面列出了各种内建的标准错误类型。
Error作为函数使用:
当像函数一样使用 Error 时 -- 如果没有 new,它将返回一个 Error
对象。所以, 仅仅调用 Error
将产生与通过new
关键字构造 Error
对象的输出相同。
const x = Error('I was created using a function call!');
const y = new Error('I was constructed via the "new" keyword!');
Error 类型
- EvalError:创建一个error实例,表示错误的原因:与 eval() 有关。不在当前ECMAScript规范中使用,因此不会被运行时抛出. 但是对象本身仍然与规范的早期版本向后兼容.
- InternalError: 创建一个代表Javascript引擎内部错误的异常抛出的实例。 如: "递归太多".该特性是非标准的,请尽量不要在生产环境中使用它!
- RangeError:创建一个error实例,表示错误的原因:数值变量或参数超出其有效范围。
- ReferenceError:创建一个error实例,表示错误的原因:无效引用。
- SyntaxError:创建一个error实例,表示错误的原因:eval()在解析代码的过程中发生的语法错误。
- TypeError:创建一个error实例,表示错误的原因:变量或参数不属于有效类型。
- URIError:创建一个error实例,表示错误的原因:给 encodeURI()或 decodeURl()传递的参数无效。
RangeError:
当一个值不在其所允许的范围或者集合中。
function fx () {
fx()
}
fx() // 会报错// Uncaught RangeError: Maximum call stack size exceeded// 未捕获的错误:超出最大调用堆栈大小
ReferenceError
引用错误,对象代表当一个不存在的变量被引用时发生的错误。
console.log(a) // ReferenceError: a is not defined
TypeError
数据类型不正确的错
let b = null// console.log(b.fx) // TypeError: Cannot read property 'fx' of null
SyntaxError
语法错误
let c = """" // SyntaxError: Unexpected string
错误处理
捕获错误: try ... catch
try {
let b = null
b.fx()
} catch (error) {
console.log('出错了: ', error.message)
console.log('出错了: ', error.stack)
}
console.log('捕获错误后还可以继续向下执行')
抛出错误: throw error
function handle() {
if (Date.now() % 2 === 0) {
throw new Error('时间为偶数, 不能处理逻辑')
} else {
console.log('时间为奇数, 可以处理逻辑')
}
}
try {
handle()
} catch (error) { // 捕获错误, 做相应的提示
// 执行出错: 时间为偶数, 不能处理逻辑
console.log('执行出错: ' + error.message)
}
Date
创建一个新Date
对象
let now = new Date();
语法
-
new Date()
-
new Date(value)
-
new Date(dateString)
-
new Date(year, monthIndex, day, hours, minutes, seconds, milliseconds);
- year:表示年份的整数值。 0到99会被映射至1900年至1999年,其它值代表实际年份。
- monthIndex:是从“0”开始计算的,这就意味着一月份为“0”,十二月份为“11”
- 当Date作为构造函数调用并传入多个参数时,如果数值大于合理范围时(如月份为 13 或者分钟数为 70),相邻的数值会被调整。比如
new Date(2013, 13, 1)等于new Date(2014, 1, 1),它们都表示日期2014-02-01(注意月份是从0开始的)
- 如果提供了至少两个参数,day默认是1
- 以一个函数的形式来调用 Date 对象(即不使用 new 操作符)会返回一个代表当前日期和时间的字符串。
Date()"Sat Nov 23 2019 10:15:03 GMT+0800 (中国标准时间)"` === `new Date()Sat Nov 23 2019 10:15:09 GMT+0800 (中国标准时间)
Date.UTC()/now()/parse()
Date.UTC(year, monthIndex, day, hours, minutes, seconds, milliseconds)
方法接受的参数同日期构造函数接受最多参数时一样,返回从1970-1-1 00:00:00 UTC
到指定日期的的毫秒数。
Date.now()
方法返回自1970年1月1日 00:00:00 UTC
到当前时间的毫秒数。
Date.parse()
方法解析一个表示某个日期的字符串,并返回从1970-1-1 00:00:00 UTC
到该日期对象(该日期对象的UTC时间)的毫秒数,如果该字符串无法识别,或者一些情况下,包含了不合法的日期数值(如:2015-02-31),则返回值为NaN。
Date.UTC(1970, 0, 1, 0, 0, 3) // 3000
Date.now() // 1574475446412
Date.parse("Aug 9, 1995")
Date.prototype原型中的方法
- getFullYear(): 根据本地时间,返回指定日期的年份,此方法替代 getYear() 。
- getMonth: 根据本地时间,返回一个指定的日期对象的月份,为基于0的值(0表示一年中的第一月)。
- getDate(): 根据本地时间,返回一个指定的日期对象为一个月中的哪一日(从1--31)。
- getHours(): 根据本地时间,返回一个指定的日期对象的小时。
- getMinutes(): 根据本地时间,返回一个指定的日期对象的分钟数。
- getSeconds(): 根据本地时间,返回一个指定的日期对象的秒数。
- getMilliseconds() : 根据本地时间,返回一个指定的日期对象的毫秒数,返回一个0 到 999的整数。
- getDay(): 根据本地时间,返回一个具体日期中一周的第几天,0 表示星期天。
- getTime: 的返回值一个数值,表示从1970年1月1日0时0分0秒(UTC,即协调世界时)距离该日期对象所代表时间的毫秒数。
- getTimezoneOffset(): 方法返回协调世界时(UTC)相对于当前时区的时间差值,单位为分钟。如果本地时区晚于协调世界时,则该差值为正值,如果早于协调世界时则为负值。例如你所在时区为 UTC+10(澳大利亚东部标准时间),将会返回 -600
new Date().getFullYear() // 2019
new Date('Sat Nov 23 2019 12:20:08 GMT+0800 (中国标准时间)').getMonth() // 10
new Date('Sat Nov 23 2019').getDate() // 23
new Date('10 17, 03:16:00').getHours() // 3
new Date('0, 03:12').getMinutes() // 12
new Date('011111, 03:12:1').getSeconds() // 1
new Date().getMilliseconds() // 202
new Date('August 19, 1975 23:15:30').getDay() // 2
new Date('Thu Jan 01 1970 00:00:00 GMT+0000').getTime() // 0
new Date().getTimezoneOffset() // -480
getTime测量代码执行时间
var end, start, i;
start = new Date();
for (i = 0; i < 1000; i++) {
Math.sqrt(i);
}
end = new Date();
console.log("Operation took " + (end.getTime() - start.getTime()) + " msec");
setFullYear(yearValue, monthValue, dayValue)
方法根据本地时间为一个日期对象设置年份。setMonth(monthValue, dayValue)
方法根据本地时间为一个设置年份的日期对象设置月份。setDate(dayValue)
方法根据本地时间来指定一个日期对象的天数。一个整数,表示该月的第几天。如果为dayValue
指定0,那么日期就会被设置为上个月的最后一天。setHours(hoursValue, minutesValue, secondsValue, msValue)
方法根据本地时间为一个日期对象设置小时数,返回从1970-01-01 00:00:00 UTC 到更新后的日期对象实例所表示时间的毫秒数。
如果dayValue被设置为负数,日期会设置为上个月最后一天往前数这个负数绝对值天数后的日期。-1会设置为上月最后一天的前一天(例如当前为4月,如果setDate(-2),则为3月29日)setMinutes(minutesValue, secondsValue, msValue)
方法根据本地时间为一个日期对象设置分钟数。setSeconds(secondsValue, msValue)
方法根据本地时间设置一个日期对象的秒数。setMilliseconds(msValue)
方法会根据本地时间设置一个日期对象的豪秒数。setTime()
方法以一个表示从1970-1-1 00:00:00 UTC计时的毫秒数为来为Date对象设置时间。
monthValue
:一个0到11之间的整数值,表示从一月到十二月。dayValue
:一个1到31之间的整数值,表示月份中的第几天。msValue
:一个 0 到 999 的数字,表示微秒数- 如果有一个参数超出了合理范围,setHours 会相应地更新日期对象中的日期信息。例如,如果为 secondsValue 指定了 100,则分钟会加 1,然后秒数使用 40。
var date = new Date('August 22, 2019 23:15:30')// date 的值 Thu Aug 22 2019 23:15:30 GMT+0800 (中国标准时间)
date.setFullYear(2020) // date 的值 Sat Aug 22 2020 23:15:30 GMT+0800 (中国标准时间)
date.setFullYear(2020, 14, 3) // date 的值 Wed Mar 03 2021 23:15:30 GMT+0800 (中国标准时间)
date.setMonth(-1) // Thu Dec 03 2020 23:15:30 GMT+0800 (中国标准时间)
-
toLocaleString()
方法返回该日期对象的字符串 -
toLocaleDateString()
方法返回该日期对象日期部分的字符串 -
toLocaleTimeString()
方法返回该日期对象时间部分的字符串 -
toString
方法总是返回一个美式英语日期格式的字符串。 -
toDateString()
方法以美式英语和人类易读的形式返回一个日期对象日期部分的字符串。 -
toTimeString()
方法以人类易读形式返回一个日期对象时间部分的字符串,该字符串以美式英语格式化。 -
toUTCString()
方法把一个日期转换为一个字符串,使用UTC时区。 -
toISOString()
方法返回一个 ISO格式的字符串: YYYY-MM-DDTHH:mm:ss.sssZ。时区总是UTC(协调世界时),加一个后缀“Z”标识。 -
toJSON()
方法返回 Date 对象的字符串形式。 -
valueOf()
方法返回以数值格式表示的一个 Date 对象的原始值,从1970年1月1日0时0分0秒(UTC,即协调世界时)到该日期对象所代表时间的毫秒数。
new Date(1993, 6, 28, 14, 39, 7).toLocaleString() // "1993/7/28 下午2:39:07"
new Date(1993, 6, 28, 14, 39, 7).toLocaleDateString() // "1993/7/28"
new Date(1993, 6, 28, 14, 39, 7).toLocaleTimeString() // "下午2:39:07"
new Date(1993, 6, 28, 14, 39, 7).toString() // "Wed Jul 28 1993 14:39:07 GMT+0800 (中国标准时间)"
new Date(1993, 6, 28, 14, 39, 7).toDateString() // "Wed Jul 28 1993"
new Date(1993, 6, 28, 14, 39, 7).toTimeString() // "14:39:07 GMT+0800 (中国标准时间)"
new Date(1993, 6, 28, 14, 39, 7).toUTCString() // "Wed, 28 Jul 1993 06:39:07 GMT"
new Date(1993, 6, 28, 14, 39, 7).toISOString() // "1993-07-28T06:39:07.000Z"
new Date(1993, 6, 28, 14, 39, 7).toJSON() // "1993-07-28T06:39:07.000Z"
new Date().valueOf() // 1574486342597
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!