A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 没名字i 于 2020-4-9 10:02 编辑

js中类型转换分为显示转换和隐式转换,下面我总结一下都有哪些情况会发生类型转换。

一.显示转换
1.通过调用 parseInt、parseFloat、new Number()等都会发生显示转换。在转换中的规则如下:


第一个字符是有效数字,就会将有效数字部分转换为数值;
[AppleScript] 纯文本查看 复制代码
console.log(parseInt('123abc')); // 123


第一个字符是非数字,就会转换为NaN;
[AppleScript] 纯文本查看 复制代码
console.log(parseInt('abc123')); // NaN


那么请看一下下面这道显式转换题:
[AppleScript] 纯文本查看 复制代码
var str = 'abc123',
    num = parseFloat(str);
if (num === NaN) {
    alert(NaN);
} else if (num === 123) {
    alert(123);
} else if (typeof num === 'number') {
    alert('number');
} else {
    alert('str');
}
// 结果是: 'number'

最终输出'number',原因是str第一个字符非数字,会转换成NaN,众所周知的NaN是不全等与NaN的。而typeof NaN是number,所以输出结果是'number'

二、隐式转换
众所周知,js中当遇到+ - * / > < ==等运算符的时候,会发生隐式转换。而+和其他运算符有一些不同。除了+,其他都会转换为数值型。
1.+操作符


对于+,遇到字符串那么就会按照字符串拼接去计算,而不是简单的加运算。
console.log('123'+ 456); // 123456
复制代码

当非数字类型遇到+的时候,也会发生隐式类型转换。
[AppleScript] 纯文本查看 复制代码
// Boolean类型遇到数值,会转换成数值型。 true=1; false=0
console.log(true+1); // 2
console.log(false+1); // 1
console.log(false + false); // 0
console.log(true + true); // 2

// 当Boolean遇到字符串,会转换成字符串
console.log(true+'1'); // true1

当+作为***一元操作符***的时候,其位于操作树的前面。如果操作数不是一个数值,会尝试将其转换成一个数值。这时候就发生隐式转换了。尽管一元负号也能转换非数值类型,但是一元正号是转换其他对象到数值的***最快方法***,也是***最推荐***的做法,因为它不会对数值执行任何多余操作。遇到不能转换的返回NaN。会将布尔类型、null、字符串转换为数值型。
[AppleScript] 纯文本查看 复制代码
+3     // 3
+"3"   // 3
+true  // 1
+false // 0
+null  // 0
+function(val){ return val;} //NaN


看如下一道面试题:
[AppleScript] 纯文本查看 复制代码
var a = 'abc' + 123 + 456;
alert(a); // abc123456
var b = '456' - '123'; 
alert(b); // 333
var c = 1,
    d = '1';
var f = c > d ? (c < d ? c : d) : (c == d ? c : d);
alert(f); // 输出1

2.其他的隐式转换


当作为对象属性的key值时,所有类型都会被toString()。
[AppleScript] 纯文本查看 复制代码
var a = {};
b = 123;
a = 'hello';
console.log(Object.keys(a)) // ["123"]

所以看如下一道面试题:
[AppleScript] 纯文本查看 复制代码
// 题一
var a={}, b='123', c=123;  
a='b';
a[c]='c';  
console.log(a); // 都会转换为字符串123,所以 a[c]会覆盖a,输出 c
-----------------------------
// 题二
var a={}, b=Symbol('123'), c=Symbol('123');  
a='b';
a[c]='c';  
console.log(a); // Symbol是生成唯一值的。 所以b不等于c,输出 'b'
------------------------------
// 题三
var a={}, b={key:'123'}, c={key:'456'};  
a='b';
a[c]='c';  
console.log(a); // 对象类型作为属性名,都会被转换为string,所以a会被a[c]覆盖掉。输出'c'

三、类型判断方法
类型判断的方法有typeof、instanceof、Object.prototype.toString.call(xxx) === '[object yyy]'。他们都有哪些优缺点呢?
1.typeof
它只能判断基本数据类型有:number、string、boolean、symbol、undefined。对于对象类型和null,统一都返回object.
[AppleScript] 纯文本查看 复制代码
console.log(typeof '123'); // string
console.log(typeof 123); // number
console.log(typeof false); // boolean
console.log(typeof Symbol(123)); // symbol
console.log(typeof undefined); // undefined

console.log(typeof null); // object
console.log(typeof new Date()); // object

2.instanceof
它用来检测构造函数的 prototype 属性是否出现在某个实例对象的原型链上。就是检测某个实例对象是不是该函数的实例
[AppleScript] 纯文本查看 复制代码
function Car(make, model, year) {
  this.make = make;
  this.model = model;
  this.year = year;
}
const auto = new Car('Honda', 'Accord', 1998);

console.log(auto instanceof Car); //  true

console.log(auto instanceof Object); // true

3.Object.prototype.toString.call
最严谨的判断是通过Object.prototype.toString.call来判断类型。
[AppleScript] 纯文本查看 复制代码
console.log(Object.prototype.toString.call('123') === '[object String]'); // true

console.log(Object.prototype.toString.call(123) === '[object Number]'); // true

console.log(Object.prototype.toString.call(Symbol(123)) === '[object Symbol]'); // true

console.log(Object.prototype.toString.call(new Date()) === '[object Date]'); // true


链接:https://juejin.im/post/5e8d5e6251882573834ecaa4

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马