Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【JavaScript】数据类型基础 #30

Open
Tracked by #6
swiftwind0405 opened this issue Mar 28, 2020 · 0 comments
Open
Tracked by #6

【JavaScript】数据类型基础 #30

swiftwind0405 opened this issue Mar 28, 2020 · 0 comments

Comments

@swiftwind0405
Copy link
Owner

swiftwind0405 commented Mar 28, 2020

image


JavaScript 中的数据类型

image

  • 基本类型:string / number / boolean / null / undefined / symbol(es6) / bigInt(es10)
  • 引用类型:object / array / function

堆和栈

  • 程序运行的时候,需要内存空间存放数据。一般来说,系统会划分出两种不同的内存空间:一种叫做堆(heap),另一种叫做栈(stack)
  • 堆(heap)是没有结构的,数据可以任意存放,它是用于存放复杂数据类型(引用类型)的,例如数组对象、object对象等。
  • 栈(stack)是有结构的,每个区块按照一定次序存放(后进先出),栈中主要存放的是基本类型的变量的值以及指向堆中的数组或者对象的地址,存在栈中的数据大小与生存期必须是确定的。除此之外,还可以明确知道每个区块的大小,因此,stack 的寻址速度要快于 heap。
  • 栈创建的时候,大小是确定的,如果超出了浏览器规定的栈限制,就会报 stack overflow 错误,而堆的大小是不确定的,需要的话可以不断增加。

基本数据类型与引用数据类型

基本数据类型

  1. 值是不可变的

  2. 存放在栈区中

  3. 值的比较

    == : 只进行值的比较,会进行数据类型的转换。
    === : 不仅进行值得比较,还要进行数据类型的比较。

引用数据类型

  1. 值是可变的

  2. 同时保存在栈内存和堆内存
    image

  3. 比较是引用的比较

第六种基本数据类型:Symbol

ES6新增,表示独一无二的值。这个知识点以后再深入学习。

第七种基本数据类型:BigInt

BigInt数据类型的目的是比 Number 数据类型支持的范围更大的整数值。在对大整数执行数学运算时,以任意精度表示整数的能力尤为重要。使用 BigInt,整数溢出将不再是问题。

JS 中的 Number 类型只能安全地表示 -9007199254740991 (-(2^53-1))9007199254740991(2^53-1) 之间的整数,任何超出此范围的整数值都可能失去精度。

console.log(9999999999999999);            // → 10000000000000000
    
// 注意最后一位的数字
9007199254740992 === 9007199254740993;    // → true

目前的开发中,此数据类型比较少用,更多详情参考此篇文章:JS最新基本数据类型:BigInt

undefinednull 的区别

相同:

  • 都是基本类型
  • 都是虚值: Boolean(value)或者 !!value转换为布尔值时为 false

不同:

  • undefined 是未指定特定值的变量的默认值,或者没有显式返回值的函数
  • null 是“不代表任何值的值”
  • 在比较 nullundefined 时,我们使用 == 时得到 true,使用 === 时得到 false:
      console.log(null == undefined); // true
      console.log(null === undefined); // false

类型转换

显示转换与隐式转换

显示类型转换

尽管JavaScript可以自动做许多类型转换,但有时仍需要做显式转换,或者为了使代码变得清晰易读而做显式转换。

做显式类型转换最简单的方法就是使用 Boolean()Number()String()Object() 函 数。

Number( "3“ )  // 3
String(false)  // "false" 或使用false.toString()
Object(3) // Number(3)
Boolean([])  // true
Boolean('')  //  false

ECMA中,Boolean([])Boolean('') 的解释:

image

Boolean() 用的是 ToBoolean 方法;
参数为 String 中,string 长度为 0,也就是空字符串 ”” 时,Boolean 显式转换为 false,非空字符串为 true
而参数只要是 Object 类型,都被 Boolean 显示转换成 true,而众所周知,[] 数组属于 Object 类型的一种。

+ 是将字符串转换为数字的最快方法,因为如果值已经是数字,它不会执行任何操作。

隐式类型转换

JavaScript中的某些运算符会做隐式的类型转换:

x+"" // 等价于 String(x)  如88 + '6' => ’886’
+x // 等价于 Number(x).也可以写成x-0  如+'886' => number类型的886
!!x // 等价于Boolean(x) 如 !!'886' => true

检验数据类型

1. typeof

适用场景

typeof 操作符可以准确判断一个变量是否为下面几个原始类型:

typeof 'ConardLi'  // string
typeof 123  // number
typeof true  // boolean
typeof Symbol()  // symbol
typeof undefined  // undefined

还可以用它来判断函数类型:

typeof function(){}  // function

不适用场景

当用 typeof 来判断引用类型时似乎显得有些乏力了:

typeof [] // object
typeof {} // object
typeof new Date() // object
typeof /^\d*$/; // object

代码除函数外所有的引用类型都会被判定为object。
另外typeof null === 'object'也会让人感到头痛,这是在JavaScript初版就流传下来的bug,后面由于修改会造成大量的兼容问题就一直没有被修复。

2. instanceof

instanceof 操作符可以帮助我们判断引用类型具体是什么类型的对象:

[] instanceof Array // true
new Date() instanceof Date // true
new RegExp() instanceof RegExp // true

[] instanceof Array 实际上是判断 Array.prototype 是否在 [] 的原型链上。所以,使用 instanceof 来检测数据类型,不会很准确,这不是它设计的初衷:

[] instanceof Object // true
function(){}  instanceof Object // true

另外,使用 instanceof 也不能检测基本数据类型,所以 instanceof 并不是一个很好的选择。

3. toString

Object.prototype.toString.call() 最准确最常用的方式。首先获取 Object 原型上的 toString 方法,让方法执行,让 toString 方法中的 this 指向第一个参数的值。

每一个引用类型都有 toString 方法,默认情况下,toString() 方法被每个 Object 对象继承。如果此方法在自定义对象中未被覆盖,toString() 返回 "[object type]",其中 type 是对象的类型。事实上,大部分引用类型比如Array、Date、RegExp等都重写了toString方法。因此可以直接调用 Object 原型上未被覆盖的 toString() 方法,使用 call 来改变 this 指向来达到我们想要的效果。

Object.prototype.toString.call('') ;   // [object String]
Object.prototype.toString.call(1) ;    // [object Number]
Object.prototype.toString.call(true) ; // [object Boolean]
Object.prototype.toString.call(undefined) ; // [object Undefined]
Object.prototype.toString.call(null) ; // [object Null]
Object.prototype.toString.call(new Function()) ; // [object Function]
Object.prototype.toString.call(new Date()) ; // [object Date]
Object.prototype.toString.call([]) ; // [object Array]
Object.prototype.toString.call(new RegExp()) ; // [object RegExp]
Object.prototype.toString.call(new Error()) ; // [object Error]
Object.prototype.toString.call(document) ; // [object HTMLDocument]
Object.prototype.toString.call(window) ; //[object global] window是全局对象global的引用

四种相等性算法

  1. 严格相等比较 ===, indexOf, lastIndexOf 认为 NaNNaN 不等,+0-0 相等
  2. 非严格相等比较 ==
  3. 同值 Set,Map,include等 认为 NaNNaN 相等,+0-0 相等
  4. 同值 Object.is 认为 NaNNaN 相等,+0-0 不等

参考资料

@swiftwind0405 swiftwind0405 changed the title 【Day29】数据类型 【JavaScript】数据类型基础 Apr 29, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant