JS数据类型转换

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

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

数据类型转换

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,254评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,875评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,682评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,896评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,015评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,152评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,208评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,962评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,388评论 1 304
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,700评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,867评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,551评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,186评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,901评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,142评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,689评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,757评论 2 351