美文网首页
JS数据类型转换

JS数据类型转换

作者: 酒极子 | 来源:发表于2019-02-13 20:11 被阅读33次

本博客会讲解下面几个概念

数据类型转换
内存图
垃圾回收和内存泄漏
浅拷贝与深拷贝

数据类型转换

1. 任何类型转String(字符)

  • xxx.toString(x)

注意nullundefined类型是不能用此方法将值转为String的,object则转成的结果不能与我们预期相符

下面是代码

(1).toString()  //  "1"
true.toString()  //  "true"
null.toString()  //  Cannot read property 'toString' of null 无法读取null的'toString'属性
undefined.toString()  //  Cannot read property 'toString' of undefined 无法读取undefined的'toString'属性
{}.toString()  //  Unexpcted token  突如其来的标记
({}).toString()  "[object Object]"
  • String(x)

这个方法则可以将nullundefined转为相应的字符串,object还是有之前的问题

下面是代码

String(1)  //  "1"
String(true)  //  "true"
String(null)  //  "null"
String(undefined)  //  "undefined"
String({})  //  "[object Object]"
  • x+''

利用任何数值与空字符串相加都会变成字符串,所以可以用下面这个方法

下面是代码

1+''  //  "1"
true+''  //  "true"
null+''  //  "null"
undefined+''  //  "undefined"
var o = {}
o+''  //  "[object Object]"

举个栗子,如果用1+'1',没办法去加,由于加号只能加相同类型的东西,所以会把左边的先.toString,再去加字符串"1"

1+'1'  //  "11"

2. 任何类型转number(数值)

  • Number(x)

下面是代码

Number('12345')  //  12345
Number(null)  //  0  
Number(undefined)  //  NaN
Number(true)/Number(false)  //  1/0
var a = {}
Number(a)  //  NaN
  • parseInt(x,10)

'10'是你要转换的进制,不写的话默认为十进制。
parseInt()会从头开始,能判断多少就多少,不能判断的则跳过。MDN资料

下面是代码

parseInt('12345',10)  //  12345
parseInt(null,10)  //  NaN
parseInt(undefined,10)  //  NaN
parseInt(true,10)/parseInt(false,10)  //  NaN
var a = {}
parseInt(a,10)  //  NaN
  • parseFloat(x)

parseFloat() 函数解析一个字符串参数并返回一个浮点数。MDN资料

下面是代码

parseFloat('12345')  //  12345
parseFloat(null)  //  NaN
parseFloat(undefined)  //  NaN
parseFloat(true)/parseFloat(false)  //  NaN
var a = {}
parseFloat(a)  //  NaN
  • x-0

任何东西减0也会得到你想要的值

下面是代码

'111'-0  //  111
null-0  //  0
undefined-0  //  NaN
true-0/false-0  //  1/0
var a ={}
a-0  //  NaN
  • +x

在值前面放个'+'号,能取它原本的值,以数字的形式展示

下面是代码

+'111'  //  111
+null  //  0
+undefined  //  NaN
+true/+false  //  1/0
var a ={}
+a  //  NaN

3. 任何类型转Boolean(布尔)

  • Boolean(x)

用Boolean()函数转换

  • !!x

在要转换的值前加两个感叹号就行

关于布尔,其他值转换成布尔时只有5个特殊值false,其他都是ture,这五个false值为:0NaN''(空字符串),nullundefined

4.null和undefined

因为这两个类型都只有一个值,所以不需要转换

内存图

要知道对象是由基本类型组成的,那基本类型又是由什么组成的呢?
比如,我写了"var a = 1"这行代码,计算机到底做了什么,这就需要画内存图来了解。

1.假设你有一个8G的内存条
2.操作系统开机即占用来512MB内存
3.Chrome 打开即占用 1G 内存
4.Chrome 各每个网页分配一定数量的内存
5.这些内存要分给页面渲染器、网络模块、浏览器外壳和 JS 引擎(V8引擎)
6.JS 引擎将内存分为代码区和数据区

我们只研究数据区
7.数据区分为 Stack(栈内存) 和 Heap(堆内存)
8.简单类型的数据直接存在 Stack 里
9.复杂类型的数据是把 Heap 地址存在 Stack 里,而本体数据则存在Heap里

遇到问题就画图,不要分析

  • 问题1:
var a = 1
var b = a
b = 2
请问 a 显示是几?

这时我们就画一张图


题1内存图
var a = 1

我们可以看到a先被赋值为1,然后把1存到Stack内存里

var b = a

接着b把a的Stack里的内存复制里一份放在自己里

b = 2

b的值变成了2,但是并不影响a的值
所以a还是2

  • 问题2
var a = {name: 'a'}
var b = a
b = {name: 'b'}
请问现在 a.name 是多少?

我们再画一张图


题2内存图
var a = {name:'a'}

新建一个对象,把它赋值给变量a,a其实只是记录了该对象对应的heap地址,并没有存该对象本身(a引用了该对象)

var b = a

实际上a只是把该对象的地址复制了一份给b而已,并没有新建一个对象

b = {name:'b'}

b被新赋值了一个对象,所以内存地址和对象都是新的,和a的对象没关系了,所以a.name的值为'a'

  • 问题3
var a = {name: 'a'}
var b = a
b.name = 'b'
请问现在 a.name 是多少?

画内存图~


题3内存图
var a = {name:'a'}

新建变量a储存对象{name:'a'}的地址

var b = a

b复制改变量地址

b.name = 'b'

b把该变量的的name值变成'b'
所以a.name的值就是'b'了

  • 问题4
var a = {name: 'a'}
var b = a
b = null
请问现在的a是什么?

内存图内存图


题4内存图
var a = {name:'a'}

新建一个对象,把对象的内存地址给变量a

var b = a

把a的对象内存地址复制给b

b = null

这里要注意,null不是对象,所以b并不会影响a对应的该对象,而是把自己的内存从对象内存地址变成null对应的16位二进制码

上面就是内存图的画法和介绍,平时多画内存图就不会出错了

垃圾回收和内存泄漏

如果一个对象没有被引用,它就是垃圾,将被回收

这个可以用内存图来理解

  • 内存回收1
var a = {name:xxx}
var b = {name:yyy}
b = null
垃圾回收1

当b指向的对象在b变成null后,就没有被引用来,所以这个对象就变成来垃圾,浏览器会在不确定什么时候把它的内存回收掉(视总占内存大小和cpu频率选择)

  • 内存回收2
var fn = function(){}
document.body.onclick = fn
fn = null
垃圾回收2

如上面这个代码,当浏览器把当前标签页关闭时,document就不存在了,没有人引用这些对象了,所以这三个对象都会回收

  • 内存泄漏

但是IE6的垃圾算法有问题,它无法将之前三个对象标记为垃圾,所以会一直留着

你只要不关掉整个浏览器,你的内存会会充满垃圾,无法重复利用

这就是内存泄漏

浅拷贝与深拷贝

深拷贝

var a = 1
var b = a
b = 2 //这个时候改变 b
a 完全不受 b 的影响
那么我们就说这是一个深复制(深拷贝)

对于简单类型的数据来说,赋值就是深拷贝。

对于复杂类型的数据(对象)来说,才要区分浅拷贝和深拷贝。

浅拷贝

var a = {name: 'frank'}
var b = a
b.name = 'b'
a.name === 'b' // true

因为我们对b操作后,a也变了
这就是就是浅拷贝

所谓深拷贝,就是对Heap内存进行完全的拷贝,修改该其值不影响另一个值

var a = {name: 'jiujizi'}
var b = deepClone(a) // deepClone 还不知道怎么实现
b.name = 'b'
a.name === 'a' // true

相关文章

  • 2、强制数据类型转换

    数据类型转换: 在js中,数据类型的转换有两种,分别是自动转换和强制转换 自动转换: 自动转换是用JS进行某些操作...

  • JS里的数据类型转换

    在js中,数据类型转换分为显式数据类型转换和隐式数据类型转换。 1, 显式数据类型转换 a:转数字: 1)Numb...

  • javaScript中数据类型转换方法

    JS 数据类型转换 方法主要有三种 转换函数、强制类型转换、利用js变量弱类型转换。 1. 转换函数: js提供了...

  • 数据类型转换

    JS 数据类型转换 方法主要有三种 转换函数、强制类型转换、利用js变量弱类型转换。 1. 转换函数: js提供了...

  • JavaScript的显式转换和隐式转换

    js的显式转换和隐式转换都是数据类型的转换;js的数据类型是弱类型的,即可以给变量赋值为任意的数据类型,当进行运算...

  • JS隐式数据类型转换

    隐式数据类型转换介绍 前面有总结过 JS数据类型转换 Number(), toString(), parseInt...

  • JS的基本小结

    JS基本输出方式 JS数据类型 变量 常量 变量常量小练习 声明提前 隐式转换 显示转换/强制转换

  • JavaScript学习笔记.md

    学习材料————廖雪峰js教程 数据类型 ===与== == 自动转换数据类型再比较;=== 不转换类型 (更好...

  • JavaScript基础总结

    ✍目录总览:(JS概念与组成、JS格式规范、JS基本语法【输入、输出、变量、数据类型、数据类型转换、运算符、流程控...

  • JS里的数据类型转换

    上一篇文章(JS里的数据类型)介绍了js中的数据类型。这篇主要介绍数据类型转换。 一、任意类型转字符串 转换成st...

网友评论

      本文标题:JS数据类型转换

      本文链接:https://www.haomeiwen.com/subject/hnfdeqtx.html