javaScript中的类型

js中的类型有那些?

javaScript中值的类型大致分为两类, 简单数据类型和复杂数据类型

简单数据类型有: 字符串 string , 数值 number, 布尔值 boolean, 空 null, 未定义 unifound , 符号 symbol

复杂数据类型有: 对象 object

类型和变量之间的关系

这一坨说的是引用类型的值存储在变量中的是内存中的地址,有一个案例 引用类型的值的变量作为函数的参数传递

在js中变量是没有类型的,只有值才拥有类型

js中的类型还可以分为两种, 一种基本类型(简单数据类型),和引用类型(复杂数据类型), 这两种类型的值在变量中的存储方式是不同的,基本类型在变量中存储的是值, 然而引用类型在变量中的存储是在是指针(内存中的地址,你可以把它想像成一个字符串),真正的值其实是存储在内存之中的,所以存储引用类型的值的变量之间传递的其实是指针,最终指向的都是同一个值

let obj1 = {
    name: 'name1'
}
let obj2 = obj1
obj2.name = 'name2'
console.log(obj1.name) // name2
console.log(obj2.name) // name2

因为变量 obj1 中存储的是对象的地址, 所以将obj1 赋值给了 obj2 后实际上复制的是地址,于是 obj1 和 obj2 都指向的是内存中的对象

还有一个经典的例子,引用类型的值作为函数参数的传递

let abc = {
    name: 'name1'
}
function fn(obj) {
    obj.name = 'name2'
    obj = new Object()
    obj.name = 'name3'
}
fn(abc)
console.log(abc.name) // name2

这里用的就是上面的知识点, abc 变量存储的的是对象的地址,然后调用函数将地址复制给了变量obj,obj变量先修改了内存中的对象,然后创建了一个新的对象,并且将这个对象的地址保存在了obj变量中, 到这里这个变量就和以前的那个对象没有关系了,因为它再也不是指向之前的那个变量了

对象类型中的封装对象包装

这一坨想说的是对象类型中的三个特殊类型

对象类型中其实还进行了一些划分,js提供了一些原生函数,可以通过他们创建对应的类型,原生函数有:

  • Object()
  • Array()
  • Function()
  • RegExp()
  • Date()
  • Error()
  • String()
  • Number()
  • Boolean()

我们可以通过他们来作为构造函数来创建对应的对象类型,但是这里面有三个比较特殊的对象类型,Number String Boolean, 特殊在他们本来是基本类型的值,是没有对象的属性和方法的,但是你肯定见过 '1'.toString() 这样的方法,这个出现的原因就是js的封装对象包装

首先这么做的目的是为了方便操作基本类型的值,然后你所看到的 '1'.toString(), 其实是js引擎帮你指向了 new String('1')的操作将字符串 '1', 转换成了 对象字符串 当然你也可以自己来封装基本类型对象, 但是建议你不要这样做

let bool = new Boolean(false)
if(bool) {
    console.log('abc')
}
// abc

当你自己封装后,你得到的那个已经不是原来的那个了,现在的bool其实已经是一个对象了,所以最好的选择就是交给js引擎, 让他帮你在正确的时候封装成对象,它有分寸知道啥时候封装成对象比如

console.log('1' instanceof String) // false
Object.prototype.toString.call('1') // '[object String]'

感觉好像只要用到了属性和方法它就会帮你封装成对象

出来封装外 你也可以同 valueOf 来进行拆封得到基本类型值

let str = new String('1')
console.log(str.valueOf) // '1'

javaScript中的类检测

这一坨是js中类型的检测的三种方法

使用typeof检测

console.log(typeof 1) // number
console.log(typeof '1') // string
console.log(typeof false) // boolean
console.log(typeof undefined) // undefined
console.log(typeof Symbol()) // symbol
console.log(typeof null) // object
console.log(typeof {}) // object
console.log(typeof []) // object

总结

  • 所有的对象类型返回的都是 object
  • 所有的基础类型返回的都是与之对应的
  • 特殊的只有一个null返回的也是 object, 这是因为历史遗留问题, null 不是对象
  • 使用typeof检测基本类型的数据比较好

使用instanceof检测

console.log('1' instanceof String) // false
console.log(new String('1') instanceof String) // true
let fn = function(){}
console.log(fn instanceof Function) // true
console.log(fn instanceof Object) // true

instanceof 用来检测对象类型的中, 对象类型的值都属于Object类型

通过Object.prototype.toString.call() 来检测

使用Object.prototype.toSting.call() 检测对象, 会返会 '[object calss]' 这里的[[class]]是对象的特性,一般与构造函数像对应

Object.prototype.toString.call('1')  // '[object String]' 再次强调 '1' 是基本类型的值, 是js引擎将他封装成了对象
Object.protytype.toString.call(fn) // '[object Function]'

js中类型的转换

Symbol.toPrimitive

=== 和 == 的区别

== 是咋比较的

首先比较两边的类型, 如果类型不同就开始进行类型的转换, 转换的规则

  • 如果是null 和 undefined 返回的是 true
  • 如果两边有一个为NaN, 返回false
  • 如果其中有一个是布尔值, 将这个布尔值转换成数字,然后再按照规则比较
  • 如果一方是数字一方是字符串,将字符串转为数字
  • 如果其中有只有一个为对象类型的化,将对象类型转换成基本类型
[] == ![] //  true

首先 ! 运算符优先级比 == 高 所以先进行 ![] 转换, 这个是转换成布尔值, 除了 '' , NaN , null , undefined, 为true,其他的都是 false , 这时候 就是 [] == false , 有一侧为布尔值将布尔值转换成数字, [] == 0 , 两边只有一个对象,将对象转换成 基本类型的值 , [] 没有valueOf()方法,所以调用toString() 方法 '' == 0 ,一侧为字符串,一侧为 数字 将字符串转为数字 0 == 0 , 最终返回 true...哎

=== 比较

== 和 === 之间的区别式, == 运行强制类型转换, 然而 === 不允许强制类型转换, 单纯的就是 你们相不相等

posted @ 2019-12-16 21:09  达文西9527  阅读(185)  评论(0编辑  收藏  举报