JavaScript数据类型(21)
JavaScript类型简介
- 类型转换
- 各种类型的API
- 内存图
- 深拷贝VS浅拷贝
JS的七种数据类型:number,String,boolean,null,undefined,object,symbol
(除了object是复杂数据类型以外,其余都是简单数据类型)
- number,boolean,转换为String类型可以使用toString() API
另外要特别注意的是:
undefined不会转换为String类型
null也不能转换成String类型,因为null没有toString这个API
最后还有2种快捷的方法:
(1)内容与''结合
1+'' //"1"' ''是空字符串
true+'' //"true"
(2)利用window.string()接口
window.string(underfined) //"underfined"
- number,string,null,object转换为boolean类型
直接利用Boolean( )即可
Boolean(1) //true
Boolean('') //false
Boolean(' ') //true 空字符串为false,空格为true
当然也有一种快捷的方法:
!!类型
!! 1 //true
!! {} //true
要记住的是变成boolean只有五种false值:
0 NaN //from number
'' //from string
undefined //from undefined
null //from null
如何将其他类型转换成为number类型?
(1)Number('1')===1
(2)parseInt('1',10)===1 将字符串1转换成为十进制的数,默认情况下是转为十进制。如果后面是8,则转换为8进制,例如parseInt('011') //在别的语言是默认以0开头为八进制,而在pasInt中没有在后面特殊表明则为十进制的11
(3)parseFloat('1.23')===1.23 将字符串1.23转换为数字1.23,遇到第一个非数字的内容,则直接停止转换。例如:parseFloat('1.23NNNW2.4') //1.23
(4)'1'-0===1 一般转换的过程中这种方式转换的比较多
(5)+'1' ===1,+'-1'===-1
上述转换的方法中:第二种一般面试用的比较多,第四种开发时用的比较多。
内存图
如上图所示:当我们写完代码提交的时候浏览器首先会对代码进行变量提升
var a =undefined var b= undefined var o =undefined vac c =undefined
我们知道在JS中浮点数是以64位进行存储,而字符是以8个字节(16位)进行存储
简单变量都存储在stack栈内存中,而复杂变量都存储在Heap堆内存中
当我在第二句后面加上 b=a时,则会将b里面的内容全部变的和a相同,而对于复杂变量则不同,对象在栈内存存储的为地址,用于指向堆内存存储的具体内容
当出现
var o2 = o时
与栈内存不同的时只是指向的地址发生变化,具体内容不会变化所以在内存图方面不存在指针问题,而指针问题只存在C语言中,在JS中我们称为对象的引用
思考题:
var a = { name : 'a' }
var b=a
var b={'name' : 'b' }
a.name=?
遇到这种问题如果你是个新手的话,一定不要口算或者心算。因为即使你算对了也是碰运气,如果想做到万无一失的做对,就要画内存图。内存图的直观性虽然有点耗时间但是可以保证准确率
所以由图可以直观的看出
a.name='a'
思考题:
var a = {name:'a'}
var b=a
b.name = 'b'
a.name = ?
遇到这种问题如果你是个新手的话,一定不要口算或者心算。因为即使你算对了也是碰运气,如果想做到万无一失的做对,就要画内存图。内存图的直观性虽然有点耗时间但是可以保证准确率
所以由图可以直观的看出:
a.name = 'b'
思考题:
var a = {name:'a'}
var b=a
b = null
a = ?
遇到这种问题如果你是个新手的话,一定不要口算或者心算。因为即使你算对了也是碰运气,如果想做到万无一失的做对,就要画内存图。内存图的直观性虽然有点耗时间但是可以保证准确率
所以由图可以直观的看出:
a={name:'a'}
思考题:
var a = {n:1};
var b= a;
a.x = a = {n:2};
alert(a.x); ?
alert(b.x); ?
容易迷惑的是:a.x = a = {n:2}
可以分解为:
var a={n:1};
var b= a;
a={n:2};
a.x=a;
alert(a.x);
alert(b.x);
首先a和b指向都是34号地址,然后a={n:2}更新了一个地址54号
同时,a指向了54号地址。但是a.x还是没有发生变化,指向的是54号地址
所以a.x输出:54号中找x没有,则输出undefined;b.x在34号地址中找发现是指向54号的地址,所以就是一个对象。输出[object Obejct]
GC垃圾回收
计算机处理数据会出现很多垃圾,当垃圾被处理以后就会出现垃圾回收
那么怎么进行垃圾回收呢(记住一句话):
如果一个对象没有被引用,它就是垃圾;它就将被回收
由上图可以看出,当执行
a=b
时,指向的地址30所存放的内容没有被引用于是我们就成地址30为垃圾!思考题:
var fn =function(){}
document.body.onclick = fn
fn = null
//判断最后结果:function是不是垃圾?
当执行到前两步时:(如下图)
执行完以后:
所以由上图可以看出:function不是一个垃圾,它一直被document所使用。
深拷贝VS浅拷贝
深拷贝:
var a=1
var b=a
var b=2
//b=2 a=1
对b进行任何的改动不会影响a的值,我们称为这种行为为深拷贝
同时对所有简单类型的变量进行赋值操作都属于深拷贝,而我们在这里要研究的对象是针对于复杂类型变量(object)。
用简洁的语言表示深拷贝和浅拷贝的区别:
深拷贝:b变a不变
浅拷贝:b变致a变
例子:
var a = { name: ' a ' };
var b = a;
b.name = 'b';
//a.name = 'b'
上述简单的说明浅拷贝,但是也是做不到深拷贝的。如果想做到深拷贝只需要进行以下操作: