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的情况:

  1.  加法运算符 + String类型时,非String类型会转化成String类型,然后字符串拼接【只有有字符串,所有的其他内容都按字符串转!!!】
  2. 有对象且与对象相加时

        eg. ‘2’+ function(){} 结果是:“2function(){}”

 

4、自动转化为Number的情况:

  1. 有加法运算符,但是无String类型时,会优先转化为Number类型
  2. 除了加法运算符,其他运算符都会把运算自动转化成数值。注意!!null转为数值时为0,undefined转为数值时为NaN
  3. 第2条注意:一元运算符!!
  4. ==抽象相等比较,是Number优先!
    1. 如果存在对象,ToPrimitive()type为number进行转换,再进行后面的比较 
    2. 存在Boolean,按照ToNumber将Boolean转为1或者0,再进行比较
    3. 如果两个一个是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]”两个字符串拼接