普通类型是???
number String Boolean Symbol null undefined 6种基本类型
对象类型是???
Object 对象类型就是上面6种类型的集合 也就是复杂类型
类型的转化
image.png转化成String有四种方法
image.pngWindow.String()
使用window.String()转化成StringString() 全局方法
String(XXX)将其他类型转化成String(xxx).toString()
null
和undefined
没有toString方法,只能用''+null
将null
转化为字符串.这是与String()
的不同
其中null、undefined、object转化失败,但是(obeect).toString()可以
这个错误:不能读toString方法,说明没有这个api
有些地方会自动调用toString()
这个API,比如console.log(1)
,其实是console.log((1).toString())
.
利用+转换为String最简便方法
XXX+'' 老司机方法(利用+转换为String最简便方法)
XXX+''其中
{}+''
会变成0,但是先用变量o赋值{}之后,就是String
转化成Number的5种方法
image.png image.pngparseInt()
参数中第一个参数是要转化的值,第二个参数代表的进制
简便方法'1234'-0(常用)
image.png简便方法二+'1'取正
image.png转化成Boolean的方法
Boolean(xxx)
Boolean(XXX)!!(老司机方法)
image.png仅有的五个false值
image.pngfalsy(虚值)是在 Boolean 上下文中已认定可转换为’假‘的值,在使用强制类型转换转换成boolean时为 false。有以下五个为false,其他值都为true。
MDN Flasy
这五个特殊值分别是0 NaN null '' undefined
但是 所有的对象Object都是true
GC垃圾回收
回收内存
如果一个对象没有被引用,他就是垃圾,就会被回收(没有引用找不到他,所以要回收)
例子
image.png内存泄漏(IE6BUG)
但是IE6有bug不会清垃圾。请在结束一天工作后用下面代码清垃圾。
解决方法:
window.onunload=function(){
document.body.onclick=null;
}
内存机制
内存图
image.png最终JS分配到100M
你买一个 8G 的内存条
操作系统开机即占用 512MB.从硬盘读取到内存
Chrome 打开即占用 1G 内存
Chrome 各每个网页分配一定数量的内存
这些内存要分给页面渲染器、网络模块、浏览器外壳和 JS引擎(V8引擎)
JS 引擎将内存分为代码区和数据区
我们只研究数据区
数据区分为 Stack(栈内存) 和 Heap(堆内存)
简单类型的数据直接存在 Stack 里
复杂类型的数据是把 Heap 地址存在 Stack 里(对象包括:狭义对象,函数,数组)
JS中的内存
image.png image.png代码区和数据区(右两个)
代码区与数据区有一个关联,a存在代码区,'1'存在数据区
代码区与数据区
代码区变量提升
- 字符串,数值,都是在64位上直接存的.所以如果b=a;那么会把a上的64个比特复制给b.(深拷贝)
-
对象那个64位比特上存的是地址,因为对象大小可变,如果对象变长了,内存后面的都要往后退,所以用了一种解决方法,只在栈内存里存地址,地址指向堆,也就是存的堆门牌号,门牌号里的东西在堆里
image.png
如果对象中的o2=o;只是内存中的栈内存换复制了一个值,这个值就是o的堆内存的地址.(浅拷贝)
image.png值的存储方法,两种,基础类型六个存入stack,复合类型对象存入heap
浏览器先进行所有的变量提升(变量声明);按顺序在stack先存好对象,后期再加属性值会很麻烦,所以在stack栈内存 存 对象在heap堆内存的地址,对象的内容实际上存在堆内存里。
image.png数值与字符的存储大小
64个二进制位(比特Bit)表示数值
每个字符在 JavaScript 内部都是以16位(即2个字节)的 UTF-16 格式储存。也就是说,JavaScript 的单位字符长度固定为16位长度,即2个字节。
image.png引用
obj存了某个对象{name:'1'}地址,比如地址是是100.
那么就说obj是对象{name:'1'}的引用
对象与变量(obj)之间的关系称为引用关系
面试题
var a = 1
var b = a
b = 2
请问 a 显示是几?
答: 1
例题1var a = {name: 'a'}
var b = a
b.name = 'b'
请问现在 a.name 是多少?
答: 'b'
例题2.1 例题2.2var a = {name: 'a'}
var b = a
b = {name: 'b'}
请问现在 a.name 是多少?
答: 'a'
例题3var a = {name: 'a'}
var b = a
b = null
请问现在 a 是什么?
答: {name: 'a'}
浅拷贝例子解析2注意 b= a; b=null;是不会改变隐藏对象里的内容的,只有x.key = ‘yyy’才能改变对象里的内容,画图好理解。
下面的例子易弄混,需要注意!!!
模拟执行过程:(Heap堆内存里存着两个对象{n:1}和{n:2},地址为随机分配的addr34 和addr54)
var a = {n:1} //var a,var {n:1}, a===addr34
var b = a //var b ,b===addr34 '='是浅复制
a.x = a = {n:2} //这句话最容易理解错,首先浏览器从左往右看,再从右往左计算。
//从左往右看的时候,`a.x = a`里的第一个a, `a===addr34`,
//从右往左计算的时候,先执行a={n:2}, 执行后a的指向变了,a===addr54;b仍然指向addr34
//然后a(addr34).x=a(addr54)。故a.x = a = {n:2}执行结束后,addr34地址存的对象多了一个属性x,属性x的值为addr54,即对象{n:2}在Heap里的地址。
//而b还是指向Heap地址为addr34这个对象,即b===addr34
最后答案就是 :a.x 这里面的a 指向的是addr 54,而addr54里面没有a.x 故Undefined
b.x 里面的b 指向的是addr 34这个地址,通过上面的运算 得知 这个地址里面有x这个对象,所以b.x =addr54这个地址的{n:2}
-
垃圾回收面试考点
image.png
解析:第一个声明为fn这个对象,然后 下面的document ===fn
所以在内存中中的地址如第二张图,onclick引用了这个function,所以这个function被两个引用。
之后这个fn=null,但是function这个还是背onclick引用,所以这个function不会被垃圾回收。
-
循环引用
image.png
解析:
将上面的第一个和后面的分开来理解,首先声明一个a,这个a没有被赋值,它的值是Undefined。下一个
a={self:a}
,在这句里面,js先计算花括号里面的,它将这个a赋值给了self,这个self的值是什么,它就是a的值,a的值是什么,是undefined
,所以最后self的值就是undefined
。最后再将这个对象的值赋值给a。
下一个如何理解???
首先这个a赋值为{}。这是一个对象。然后a.self =a ,这说明在内存中是这样的
它这个里面的self的值就是a,a是什么,a是{},然后 这个a里面还会是a.self,那么a.self后面又是什么 ,还是一个{}.......一直循环
所以最后a.self.self是什么???答案就是上面最后输出的结果
网友评论