QUESTION1:JS的数据类型有哪些?
Js分为基本数据类型和对象数据类型
基本数据类型:一共六种
原始类型 -> string,number,boolean,null,undefined
ES6新增symbol类型
对象类型:也叫引用类型,array和function是对象的子类型。
QUESTION2:说说你对JavaScript是弱类型语言的理解?
Js声明变量的时候并没有声明变量的类型,变量当前的类型是由其值的类型决定的
JS中的一些转换规则
1、ToPrimitive(input [,type])
只针对引用类型object,其目的是将引用类型转换为原始类型。
总结:如果不设置type类型,对象转化时对于Date数据类型的type为String;其他数据类型的type均为Number!
转String类型:先调用toString(),如果结果不是原始类型再调用valueOf(),如果还不是原始值的话则抛出异常
转Number类型:先调用valueOf(),如果不是原始类型再调用toString(),如果还不是原始值则抛出异常
valueOf()和toString()是对象的两个方法:
- toString():返回对象的字符串表示。
- 特殊:
- 表示对象的时候结果是:“[Object Object]”
- 表示数组的时候结果是:数组内容以逗号相连的字符串
- valueOf():返回对象的字符串、数值或布尔值表示,其实就是返回该对象本身
undefined和null没有valueOf()和toString()这两个方法!
2、Boolean运算符转换规则:
只有如下几个会转换为false:undefined、null、0、-0、+0、NaN、“”(空字符串)
Boolean ( {} )
Boolean ( [] )
Boolean (new Boolean(false) 或者是 false)
结果都是true
3、自动转化为String的情况:
- 加法运算符 + String类型时,非String类型会转化成String类型,然后字符串拼接【只有有字符串,所有的其他内容都按字符串转!!!】
- 有对象且与对象相加时
eg. ‘2’+ function(){} 结果是:“2function(){}”
4、自动转化为Number的情况:
- 有加法运算符,但是无String类型时,会优先转化为Number类型
- 除了加法运算符,其他运算符都会把运算自动转化成数值。注意!!null转为数值时为0,undefined转为数值时为NaN
- 第2条注意:一元运算符!!
- ==抽象相等比较,是Number优先!
- 如果存在对象,ToPrimitive()type为number进行转换,再进行后面的比较
- 存在Boolean,按照ToNumber将Boolean转为1或者0,再进行比较
- 如果两个一个是string一个是number,则string转化为number进行比较
数据类型的判断方法
typeof:能判断出基本数据类型(但是typeof(null)结果为object),但是无法判断对象类型,除了函数(typeof(()=>{})结果为function)其他的对象都得到object结果
instanceof:有一定的缺陷,它的检测原理是根据函数的prototype是否在被检测对象的原型链上,因此出现的问题是无法判定一个值是Array还是Object
Object.prototype.toString( obj ):该方法的本质是得到了对象的内部属性[[class]],传入原始类型也可以得到结果是因为对值进行了包装。
具体使用及结果:
Object.prototype.toString.call('An') // "[object String]" Object.prototype.toString.call(1) // "[object Number]" Object.prototype.toString.call(Symbol(1)) // "[object Symbol]" Object.prototype.toString.call(null) // "[object Null]" Object.prototype.toString.call([]) // "[object Array]" Object.prototype.toString.call(undefined) // "[object Undefined]" Object.prototype.toString.call(function(){}) // "[object Function]" Object.prototype.toString.call({name: 'An'}) // "[object Object]"
QUESTION:为什么要用到call()呢?
每个继承Object的对象都有toString()方法,在toString没有被重写的情况下,执行Object.prototype.toString会返回[object type],其中type是对象的类型。
- 如果是个基本数据类型调用toString()方法,比如字符串或者是一个数字,那么toString()会直接返回内容的字符串
- 如果直接调用Object.prototype.toString()的话,默认是指向Object,因此我们这里要调用call()或者apply()来改变toString的指向
var str = 'hello';
var arr = [];
console.log(str.toString()) // hello
console.log(Object.prototype.toString(str)) // [object Object]
console.log(Object.prototype.toString.call(str)) // [object String]
console.log(Object.prototype.toString.call(arr)) // [object Array]
toString和String的区别:
|
toString |
String |
作用 |
都可以将值转为字符串 |
|
用法写法 |
null.toString() |
String( null ) |
是否可以转null和undefined |
No |
Yes |
是否可以设进制值 |
Yes |
No |
练习题:
[]+[]、[]+{}、{}+[]、{}+{}
[] 解析过程:先走valueOf(),得到结果还是[],然后执行toString(),得到“”
{} 解析过程:先走valueOf(),得到结果还是{},然后执行toString(),得到“[object object]”
[] + [] 实际是“”+“”两个空字符串拼接
[]+{} 和 {}+[] 实际是“”+“[object object]”
但是博客解释说到{}+[]的结果是0,但是我试验得到还是“[object object]”
{}+{} 实际是“[object object]”+“[object object]”两个字符串拼接