JS面试---类型转换②
类型转换
1. 其他值到字符串的转换规则?
规范中定义了抽象操作 ToString ,它负责处理非字符串到字符串的强制类型转换。
(1)Null 和 Undefined 类型 ,null 转换为 "null",undefined 转换为 "undefined",
(2)Boolean 类型,true 转换为 "true",false 转换为 "false"。
(3)Number 类型的值直接转换,不过那些极小和极大的数字会使用指数形式。
(4)Symbol 类型的值直接转换,但是只允许显式强制类型转换,使用隐式强制类型转换会产生错误。
(5)对普通对象来说,除非自行定义 toString() 方法,否则会调用 toString()(Object.prototype.toString())
来返回内部属性 [[Class]] 的值,如"[object Object]"。如果对象有自己的 toString() 方法,字符串化时就会
调用该方法并使用其返回值。
//例题1:
function judgeType(ele) {
let res = typeof ele;
if (res === "object") {
// 短路表达式,第一个成立则返回第二个的值,第一个不成立,则返回第一个的值
Object.prototype.toString.call(ele) === "[object Object]" && (res = "object");
Object.prototype.toString.call(ele) === "[object Array]" && (res = "array");
Object.prototype.toString.call(ele) === "[object Date]" && (res = "date");
Object.prototype.toString.call(ele) === "[object Null]" && (res = "null");
Object.prototype.toString.call(ele) === "[object RegExp]" && (res = "RegExp");
}
return res;
}
// ----------一般数据类型---------
console.log(judgeType(23)); // number
console.log(judgeType(false)); // boolean
console.log(judgeType("23")); // string
console.log(judgeType(undefined));// undefined
console.log(judgeType(NaN)); // number
console.log(judgeType(function () { })); // function
console.log("===============================");
// ---------- 对象类型数据---------
console.log(judgeType(null)); // object null
console.log(judgeType({})); // object object
console.log(judgeType([])); // object array
console.log(judgeType(new Date())); // object date
console.log(judgeType(new RegExp())); // object RegExp
2. 其他值到数字值的转换规则?
有时我们需要将非数字值当作数字来使用,比如数学运算。为此 ES5 规范在 9.3 节定义了抽象操作 ToNumber。
(1)Undefined 类型的值转换为 NaN。
(2)Null 类型的值转换为 0。
(3)Boolean 类型的值,true 转换为 1,false 转换为 0。
(4)String 类型的值转换如同使用 Number() 函数进行转换,如果包含非数字值则转换为 NaN,空字符串为 0。
(5)Symbol 类型的值不能转换为数字,会报错。
(6)对象(包括数组)会首先被转换为相应的基本类型值,如果返回的是非数字的基本类型值,则再遵循以上规则将其强制转换为数字。
为了将值转换为相应的基本类型值,抽象操作 ToPrimitive 会首先(通过内部操作 DefaultValue)检查该值是否有valueOf() 方法。如果有并且返回基本类型值,就使用该值进行强制类型转换。如果没有就使用 toString() 的返回值(如果存在)来进行强制类型转换。
如果 valueOf() 和 toString() 均不返回基本类型值,会产生 TypeError 错误。
// 例子:
console.log(1 + "true"); //"1true"
console.log(1 + true); // 2
console.log(1 + undefined);
// 1 + Number(undefined) = 1 + NaN = NaN
console.log(1 + null);
// 1 + Number(null) = 1 + 0 = 1
console.log("2" > 10);
// Number("2") = 2 (2 > 10) false
3. 其他值到布尔类型的值的转换规则?
ES5 规范 9.2 节中定义了抽象操作 ToBoolean,列举了布尔强制类型转换所有可能出现的结果。
以下这些是假值:
• undefined
• null
• false
• +0、-0 和 NaN
• ""
假值的布尔强制类型转换结果为 false。从逻辑上说,假值列表以外的都应该是真值。
4. ||
和 &&
操作符的返回值?
|| 和 && 首先会对第一个操作数执行条件判断,如果其不是布尔值就先进行 ToBoolean 强制类型转换,然后再执行条件
判断。
对于 || 来说,如果条件判断结果为 true 就返回第一个操作数的值,如果为 false 就返回第二个操作数的值。
&& 则相反,如果条件判断结果为 true 就返回第二个操作数的值,如果为 false 就返回第一个操作数的值。
|| 和 && 返回它们其中一个操作数的值,而非条件判断的结果
例题如例1----↑
5. Symbol 值的强制类型转换?
ES6 允许从符号到字符串的显式强制类型转换,然而隐式强制类型转换会产生错误。
Symbol 值不能够被强制类型转换为数字(显式和隐式都会产生错误),但可以被强制类型转换为布尔值(显式和隐式结果
都是 true )。
6. == 操作符的强制类型转换规则?
(1)字符串和数字之间的相等比较,将字符串转换为数字之后再进行比较。
(2)其他类型和布尔类型之间的相等比较,先将布尔值转换为数字后,再应用其他规则进行比较。
(3)null 和 undefined 之间的相等比较,结果为真。其他值和它们进行比较都返回假值。
(4)对象和非对象之间的相等比较,对象先调用 ToPrimitive 抽象操作后,再进行比较。
(5)如果一个操作值为 NaN ,则相等比较返回 false( NaN 本身也不等于 NaN )。
(6)如果两个操作值都是对象,则比较它们是不是指向同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true,否则,返回 false。
console.log(undefined == undefined); //true
console.log(undefined == null); //true
console.log(null == null); //true
console.log(NaN == NaN); //false
详细资料可以参考:
《JavaScript 字符串间的比较》
6. {} 和 [] 的 valueOf 和 toString 的结果是什么?
{} 的 valueOf 结果为 {} ,toString 的结果为 "[object Object]"
[] 的 valueOf 结果为 [] ,toString 的结果为 ""
//例子:
console.log([] == 0); // true
// [].valueOf().toString() = ""
// Number([].valueOf().toString()) = 0
console.log(![] == 0); // true
// ![] 先逻辑Boolean转换,再转换Number
// Boolean([].valueOf().toString()) = false
// Number(false) = 0
console.log(![] == []); // true
// 结合上面两题,Number(false) == Number("")
console.log([] == []); //false 地址不同
console.log({} == !{}); // false
// {}.valueOf().toString() = [object Object]
// Number({}.valueOf().toString()) = NaN
// !{} ---> Boolean({}.valueOf().toString()) = true
// Number(true) = 1
console.log({} == {}); //false
29. 如何将字符串转化为数字,例如 '12.3b'?
(1)使用 Number() 方法,前提是所包含的字符串不包含不合法字符。
(2)使用 parseInt() 方法,parseInt() 函数可解析一个字符串,并返回一个整数。还可以设置要解析的数字的基数。当基数的值为 0,或没有设置该参数时,parseInt() 会根据 string 来判断数字的基数。
(3)使用 parseFloat() 方法,该函数解析一个字符串参数并返回一个浮点数。
(4)使用 + 操作符的隐式转换,前提是所包含的字符串不包含不合法字符。
//例:
console.log(parseInt("123a")); //123
console.log(parseFloat("123.02a")); //123.02
console.log(+"123a"); //NaN
console.log(+"123"); //123
console.log(Number("123a")); //NaN