一、(似大纲)JS核心部分 【基础知识、底层管理、项目中如何应用】
1、数据类型 & 内存处理
- 有哪些类型
- 各个类型的详细解读
- 检测数据类型
- 数据类型之间的转换
- 堆栈内存 & 垃圾回收机制
- 作用域 & 闭包
- 对象、数组、正则、Date、Math...等对象的用法
- ...
2、面向对象
- 对象、实例和类之间的关系
- new
- prototype & proto
- this问题
- ...
3、DOM操作 【弱化】
- 获取关于DOM以及节点的增删改查方法
- 盒子模型(13个属性)
- DOM事件
-
- DOM0 & DOM2 事件绑定
- 事件对象
- 事件传播机制
- 事件委托
- 拖拽
- ...
- 浏览器(DOM)渲染的底层操作【DOM操作的性能优化】
- ...
4、定时器和事件循环机制
- 定时器的玩法
- reguesAnimationFrame
- 同步异步的底层处理逻辑
- Promsie及其源码
- async/await
- 迭代器和生成器
- ...
5、HTTP网络通信 & Ajax前后端数据交互
- HTTP网络相关知识
- Ajax、fatch、axios...
- 非同源策略请求
- 前端性能的优化方案
- ...
6、ECMAScript2015(ES6)& HTML5
- 基础:let/const/class、箭头函数、解构赋值、模板字符串、数组和对象新增的方法...
- ES6Moudule模块规范【单例、AMD、CMD、CommonJS、ES6Moudule】
- 进阶:Promise(saync/awite)、Generator、Iterator、Reflear、Fetch...
- Hiestory API
- canvas
- 音视频的处理
- ...
7、实战思想和设计模式
8、如何学习
- 前期:70%记忆+30%理解
- 后期:30%记忆+70%理解
1)基础知识非常重要,我们需要做出完整的较完美的思维导图
- 做笔记 并且定期梳理
- 每周抽出定期的时间把笔记从头到尾过一遍
2)实战项目如何学习(切忌思维懒惰)
老师讲完案例后:
- 自己去每一行加注释(达到中文编程的地步)
- 第一遍(听明白):注释&参照老师的代码写一遍(不会赶紧问)
- 第二遍(自己写出来):关闭老师代码,自己按照注释去写,哪块写不出来证明那块基础知识不扎实
- 第三遍...直至写出来注释删掉,开始裸写
- 直至自己能写出
- 间隔两三天,在写一回
- 费曼学习法
- 教别人
9、学习态度
1)汤之盘铭曰:苟日新、又日新、日日新。
2) IT行业 一定要有”求索“之心
3)学习没有技巧:唯一的技巧就是努力付出
二、
1、复习
JS中的数据类型
- 原始值类型【基本数据类型/值类型】
-
- Number 数字
- string 字符串
- boolean 布尔
- null 空
- undefined 未定义
- Symbol 唯一值【ES6新增】
- Bigint 大数 【ES6新增】
- 对象类型
-
- 标准普通对象:例如:{}
- 标准特殊对象(对象类型的实例):例如:
-
-
- new Array 数组
- new Regexp 正则
- Math 数字函数对象
- new Date 日期对象
- new Error 错误对象
- Set/Map 【ES6新增的数据结构】
-
-
- 非标准特殊对象(原始值对应的‘对象类型’的实例):例如:new Number(1)
- 函数对象:function
2、创建一个数字(装箱&拆箱):
- 字面量(创建的是 原始值) :var num = 10;
- 构造函数(创建出来的是非标准特殊对象):var num2 = new Number(10);
num1 vs num2
-
- 一个是原始值,一个是对象
- num2是Number类的一个实例,可以直接调用Number.prototype上的方法
- 从严格意义上讲:num1不是Number类上的实例(因为实例都是对象类型的)按理来说应该是无法调用Number.prototype上的方法的,但是在实际应用中是可以调用的,所以也可以称num1为Number的实例(由此引出‘装箱’&‘拆箱’知识点):
-
-
- 浏览器在执行这段代码num1.toFixed(2)时会转化到-->new Number(num1) 默认会把原始值转换为对象,然后再去调用toFixed的方法,我们会把这种操作(把原始值转化为实例对象的过程)称之为“装箱”!!
- num2+10--> 浏览器会默认把实例对象转换为对应的原始值,然后在进行数学运算,这个过程称之为“拆箱”
-
-
- 装箱方法:new Number(num) || Object(num)
- 装箱操作:new只能给Number/String/Boolean使用
Object都可以但是null/undefined会返回空对象,Symbol会返回对象 - 拆箱:把对象转化为原始值
-
-
- 首先嗲用对象的“Symbol.toPrimitive”函数
- 如果对象不具备这个属性,则调用“对象.valueOf()”这个属性,看获取的是不是原始值,是原始值则实现目标
- 如果不是原始值,则继续调用“对象.toString()”函数,把其转化为字符串
- 如果最后的目的是变为数字,则再把字符串转化为数字
例如:
-
var num2 = new Number(10);
console.log(num2+10)
num2[Symbol.toPrimitive] ->undefined
num2.valueOf() ->10
10+10=>20
3、零碎知识汇总
- 成员访问:obj.xxx
- parentInt/parentFloat
作用:都是用来把其他值转换为数字的
查找过程:从字符串(不是字符串的,也要先转换为字符串)左侧第一个字符开始查找,把找到大的有效数字转换为数字,遇到一个非有效的,则停止查找!一个都找不到,结果是NaN! - NaN 不等于任何数
- “+”在JS中比较特殊:除了数字运算,还有字符串拼接\
- 加号两边有一边是字符串就一定是字符串拼接\
- 加号两边有一边是对象,则可能会字符串拼接([10]+10)
- /i++/++i/--i/i-- 肯定是数学运算(不论i是啥类型的值,都要首先转化为数字)
/i=i+1/i+=1 不一定是数学运算,还有可能是字符串拼接**
**+val 把val转化为数字 - “==”连接情况
对象==字符串 (对象转换为字符串)
对象==对象 (比较的是内存地址)
null==undefined (null、undefined除了互相相等和本身、与别的值都不相等)
NaN != NaN
其余情况只要是类型不一致,就是转数字
布尔==字符串 都转换为数字
4、浏览器处理机制细节
- 虚拟内存:内存条
物理内存:硬盘
堆栈内存都是从虚拟内存分配出来的空间 - 打开页面时浏览器操作
- 开辟堆栈内存
- 堆内存中默认开辟了一个空间GO
- 存储浏览器内置的API
- 创建全局上下文EC(G)并进栈执行
- VO(G)存储全局上下文中声明的对象
- 默认创建一个全局变量window,指向GO全局对象,所以基于window.xx就可以访问内置API
- 变量提升:
当前上下文中,执行代码前,首先会把带“var/function”关键字的进行提前声明或者定义\- var 只声明
- function 声明加定义 全局上下文中,基于var/function声明的变量,不会存储到VO(G)中,而是存储到GO(window)中,但是基于let/const声明的变量,直接存储到VO(G)中!
- let xxx =xxxx 排除变量提升的优先顺序
1、先创建值- 原始值直接存储到栈内存中
- 对象类型存储到堆中,在把16进制的内存地址赋值给变量 2、再声明变量 3、让变量和值关联(赋值、定义)
- 函数创建
1、开辟堆内存空间(16进制地址)
2、储存三部分内容- 声明其作用域(在哪个上下文创建的那么其作用域就是谁)
- 存储函数体中的代码(按照字符串存储)
- 和普通对象一样,存储键值对
- name 函数名
- length 形参个数
- prototype
- proto 3、把空间地址赋值给函数名(变量名)
- 函数执行
1、开辟一个全新的私有执行上下文并进栈执行- EC(?)
- AO(?) 私有变量对象:存储当前上下文中声明的私有变量的 2、代码执行前处理的事情
- 初始化作用域链<函数私有上下文,函数作用域>
- 初始化this指向
- 初始化arguments
- 形参赋值(形参是私有变量)
- 变量提升
3、代码执行
4、私有上下文的释放问题
练习
场景:一个变量取不同值问题
/*
解决方案一:利用“==”会进行数据类型转换,再利用对象转数字要经过四步,此时我们重写其中某一步,拿到自己想要的值即可
var a = [1,2,3];
a.toString = a.shift;
if(a==1&&a==2&&a==3){
console.log('ok');
}
方案二、
var i=0
//数据劫持
Object.defineProperty(window,'a',{
get(){
return ++i;
}
})
*/
/* for (var i = 0; i < 5; i++) {
(function (i){
setTimeout(function () {
console.log(i);
}, (i + 1) * 1000)
})(i)
}
*/
/*
//利用let 原理依旧是闭包,利用循环中的let可以产生“私有块级上下文”也是创建5个闭包,分别保存i的值,给对应的定时器
+ 先产生一个父级私有块级上下文,用来控制循环的
+
for(let i = 0;i<5;i++){
setTimeout(() => {
console.log(index);
}, (i + 1) * 1000)
}
*/
/* // 定时器支持第三个及以后的参数:定时器到时间,把函数执行,会把后边的参数值,传递给这个函数
// + 原理还是闭包:只不过是用的定时器内部大的闭包处理机制
for (var i = 0; i < 5; i++) {
setTimeout(function (x) {
console.log(x);
}, (i + 1) * 1000, i)
} */