文章目录
基本数据类型
- null
- undefine
- symbol
- number
- string
- boolean
- bigint
引用数据类型
- object
- array
- re
- date
- math
- function
数据类型检测
- typeof 检测数据类型的逻辑运算符
- instanceof 检测实例
- constructor 检测构造函数
- Object.prototype.toString.call 检测数据类型
typeof 无法区分object与array
其他基本类型都能区分 引用类型中object与function也都能区分 如图:
但是不能区分array与object 为啥呢?
笔者认为,因为var作为引用类型 存地址 typeof循着地址过去内存空间中找
而数组在内存中,就是连续存储的对象集合
所以typeof即便找到数组 也只能识别成对象(也就是抓到数组的第一个元素就完事了 没有继续找 或者说没有根据继续找 第二个元素谁知道是数组的元素还是别的对象了呢)
typeof特点
- 识别结果用字符串返回
- 认为null array都是object(确实可以这么看 即,识别不够准确)
NaN 有效数字问题
意思 不是有效数字的任意值 所以 它和任何值都不相等 因为这个是抽象的 没有具体值
所以NaN == NaN
是false
那么检测这种抽象概念就要用个抽象的函数:isNaN
只有这个可以捕捉到NaN
有意思的是 typeof NaN === "number"
因为不是有效数字也是number对象的一员
转数字操作
- Number
- 浏览器底层转换机制 即
- true -> 1
- false -> 0
- null -> 0
- undefine -> NaN
- Number 必须保证整个字符串都能转成数字 如“12abc”就不行 ; “12”可以
- 浏览器底层转换机制 即
- parseInt
- 从字符串左侧挨个找有效数字(当然先做字符串转换数字操作)
- 直到遇到NaN结束
- parseInt("") == NaN
- parseInt(“12abc”) == 12
- isNaN
- 先调用浏览器底层转换机制 之后再判断
- isNaN(null) == isNaN(0) == false
- isNaN("") == isNaN(0) == false
- isNaN(undefine) == isNaN(NaN) == true
- isNaN(“12abc”) == isNaN(NaN) == true
IIFE
Immediately Invoked Function Expression
- 隐藏具体实现
- 不污染全局变量空间
(function () {
var a=3;
console.log(a+3);
})()
是一个立即执行且不暴露内部的函数IIFE
如果想让外界获取 可以有以下形式:
(function () {
var a=3;
function inner (){
console.log(a+3);
};
function outer () {
console.log(a++);
};
window.$ = function () {
return {
outer:outer;
}
}
})()
$().outer()
函数 与 this
- 任何函数都是被某对象调用的
- this指示这个对象
prototype constructor
Date.prototype.constructor === Date
闭包
function fn1() {
var a =2;
var b = 3;
function fn2() {
console.log(a);
}
}
fn1()
闭包产生条件
- fn1得到执行
- 子函数调用父函数的变量与函数
理解
- 嵌套的内部函数
- 被引用变量(函数)的对象
应用
- 将函数作为另一个函数的返回值
- 将函数作为实参传递给子函数用
function showDelay(msg,time) {
setTimeout(function () {
alert(msg)
},time)
}
}
传递msg进去setTimeout 反过来说 子函数setTimeout引用了父函数的参数msg
内存溢出与内存泄漏
内存泄漏 就是用完的东西不放回去 用完的内存不释放
当内存泄漏过多的时候 超过句柄可用内存上限 就会出现内存溢出
内存泄漏有三种可能的情况
- 局部变量定义不当 导致解释为全局变量 用完不回收
- setInterval定时器进程没有clear释放
- 闭包里面保护的局部变量不释放 或者说那个对象没有释放
浏览器内核
主线程
- js引擎模块 js程序解析
- html css文档解析模块
- DOM/CSS 上面文档解析以后 DOM和css在内存的运行 生成一个个对象在内存中跑
- 布局渲染模块 负责布局 效果的绘制 即内存对象产生后如何用对象
分线程
- 定时器模块
- 事件event响应模块
- 网络请求 ajax
JS引擎 单线程 而且是主线程执行
setTimeout是在分线程 把定时间的长度以及回调函数设定好就行了 是浏览器的分线程 和JS引擎无关
事件驱动模型
回调函数的执行也是要排队的 放在回调队列中(callback queue)
当然 先要等初始化代码执行完
- dom绑定
- 设置定时器
- ajax请求
之后 等待event loop事件循环的轮询 从队列中抓回调函数出来 到执行栈中做事:)
而且 JS单线程 因此队列的回调函数只能一个个做
堆 heap 存放对象
栈 stack 存放变量 属性
执行栈 = code segment 所有代码在这里执行
队列
- 任务队列
- 消息队列
- 事件队列
- 回调队列
都是一个东西 看你吧函数抽象成 任务task 还是消息info 还是event时间 还是回调callback
请求响应模型
request response model
web worker 多线程解决方案
将大计算量代码交由web worker分线程运行 而不冻结用户使用的页面
但是子线程不能操作DOM 不能调用window对象的方法
因为 子线程的全局this是一个特殊的scope 但绝不是window 因此window类的方法都没法用 只能做基本的计算了。。。
- 主线程代码
- 子线程代码
类似JS引擎的单线程 有消息队列
我们worker的主分线程也同样有消息队列:)