JavaScript学习笔记三
- 个人学习笔记
- 参考阮一峰的JavaScript教学
- 类型转换,内存,深拷贝,关于内存的面试题等等
转换为String
toString()
方法
null
和undefined
没有toString
方法,只能用''+null
将null
转化为字符串.这是与String()
的不同
这个错误:不能读toString方法,说明没有这个api
有些地方会自动调用toString()
这个API,比如console.log(1)
,其实是console.log((1).toString())
.
利用+
转换为String最简便方法
String()
全局方法
转换为Number:五个方法
parseInt()
注意里面是字符串的情况
简便方法'1234'-0
(常用)
简便方法二+'1'
取正
转换为布尔
Boolean()
!!
简便方法转换为布尔
仅有的五个false值
内存图
最终JS分配到100M
- 你买一个 8G 的内存条
- 操作系统开机即占用 512MB.从硬盘读取到内存
- Chrome 打开即占用 1G 内存
- Chrome 各每个网页分配一定数量的内存
- 这些内存要分给页面渲染器、网络模块、浏览器外壳和 JS引擎(V8引擎)
- JS 引擎将内存分为代码区和数据区
- 我们只研究数据区
- 数据区分为 Stack(栈内存) 和 Heap(堆内存)
- 简单类型的数据直接存在 Stack 里
- 复杂类型的数据是把 Heap 地址存在 Stack 里(对象包括:狭义对象,函数,数组)
JS中的内存
代码区和数据区(右两个)
代码区与数据区有一个关联,a存在代码区,'1'存在数据区
代码区与数据区
代码区变量提升
-
字符串,数值,都是在64位上直接存的.所以如果b=a;那么会把a上的64个比特复制给b.(深拷贝)
-
对象那个64位比特上存的是地址,因为对象大小可变,如果对象变长了,内存后面的都要往后退,所以用了一种解决方法,只在栈内存里存地址,地址指向堆,也就是存的堆门牌号,门牌号里的东西在堆里.
-
如果对象中的
o2=o;
只是内存中的栈内存换复制了一个值,这个值就是o的堆内存的地址.(浅拷贝)
- 值得存储方法,两种,基础类型六个存入stack,复合类型对象存入heap
数值与字符的存储大小
64个二进制位(比特Bit)表示数值
每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。
引用
obj存了某个对象{name:'1'}
地址,比如地址是是100.
那么就说obj是对象{name:'1'}
的引用
对象与变量(obj)之间的关系称为引用关系
关于内存的面试题
var a = 1
var b = a
b = 2
请问 a 显示是几?
1 (深拷贝)
var a = {name: 'a'}
var b = a
b = {name: 'b'}
请问现在 a.name 是多少?
'a'
var a = {name: 'a'}
var b = a
b.name = 'b'
请问现在 a.name 是多少?
'b'
var a = {name: 'a'}
var b = a
b = null
请问现在 a 是什么?
{name: 'a'}
循环引用
上面因为最开始定义a是
undefined
的,所以self也为undefined
的这个是因为a已经声明为一个对象了,所以现在a的栈内存里面存的是一个地址,然后再把self赋值为a,就是把a的地址放到了a.self中,形成了引用的循环嵌套
引用类型面试题
赋值语句和三元?:
是从右边开始看的.右结合
陷阱:
a.x = a = {n:2}
浏览器先从左往右看,再从右往左看解析:
- 先从左往右看的时候,不管a.x还是后面的a,a都是34.
-
然后从右往左看,把{n:2}的地址付给了中间的a,最左边的a.x地址没变,还是34.
GC垃圾回收
回收内存
如果一个对象没有被引用,他就是垃圾,就会被回收(没有引用找不到他,所以要回收)
例子
题目
前两句话
第三句话
所以结果:不是垃圾.不会回收
内存泄漏(IE6BUG)
在ie6的时候,如果关闭页面,一些垃圾是没有被清除,内存被永久的占用了
深拷贝和浅拷贝
对于基本类型来说
赋值就是深拷贝,因为b变不影响a
对象
对象的赋值是浅拷贝
而对象的深拷贝
就是地址不一样,但是两者在heap里的是一样的