JS整理

js基础笔记以及一些数组基本API

变量提升机制

1. 什么是变量提升?

在“当前上下文”中,代码执行之前,浏览器首先会把所有带var/function关键字的进行提前声明或者定义
@1 带var的只是提前声明
@2 带function的,此阶段声明+定义{赋值}都完成了

2. let/const/import/class声明的变量不存在变量提升
3. 重复声明的问题
4. 推荐使用函数表达式,确保函数执行只能放在“创建函数代码”的下面,保证逻辑的严谨性
5. 条件判断中的变量提升「先聊var」
在当前上下文中,变量提升阶段,不论条件是否成立,都要进行变量提升
「条件是否成立,是执行代码阶段确定的事情,变量提升的时候,代码还没执行」;
带var的和之前一样,只声明不赋值;“判断体中出现的function”,在变量提升的时候
,也只是声明但不赋值了...;

函数的底层运行机制

  1. 形成一个私有的执行上下文(AO),然后进栈执行
  2. 初始化作用域链
  3. 初始化THIS
  4. 初始化ARGUMENTS
  5. 形参赋值
  6. 变量提升
  7. 代码执行
  8. 根据情况决定是否出栈释放
  • 特殊匿名函数具名化
  • 设置的名字,并不会在所处上下文中进行声明
  • 在函数执行形成的私有上下文中,会把这个名字作为一个私有变量「存储到AO中」,变量值是当前函数本身「堆内存地址」; 并且默认情况下,对这个变量值进行修改是无效的
  • 但凡函数内部,这个名字被我们手动的声明过「例如:形参/var/function/let/const…」,都认为这个名字是我们自己玩的私有变量,和默认值是当前函数本身没关系了!! “默认是函数本身的这个点,权重太低”
    ES6中的块级上下文 “代码执行期间产生的”
  • 除“函数和对象”的大括号外「例如:判断体/循环体/代码块…」,如果在大括号中出现了 let/const/function/class 等关键词声明变量,则当前大括号会产生一个“块级私有上下文”;它的上级上下文是所处的环境;
  1. let/const/function/class会产生块级上下文,也会受到块级上下文的束缚
  2. var不产生,也不受块级上下文的影响
    函数在块级上下文中的特殊性 {新版本和老版本的不同}
    老版本:不会有块级上下文,所以在大括号(初函数和对象外)中出现function,还是保持原始的样子,变量提升阶段是声明+定义的;新版本:为了兼容ES5也可以兼容ES6,则全局下也要声明,私有块级上下文中也要声明;
  3. 出现在“除函数/对象”以外的大括号中的function,在最开始变量提升阶段只声明
  4. 会产生块级上下文,并且进入块级上下文中的第一件事情是“变量提升:声明+赋值”

闭包

闭包机制:函数执行会产生一个全新的私有上下文
  • @1 保护:保护里面的私有变量不受外界的干扰,防止全局变量污染
  • @2 保存:一但这个上下文不被释放,里面的私有变量和值,就保存起来了,可以供其“下级”上下文中调取使用
    我们函数执行产生的两大机制“保存/保护”,称之为闭包机制!!
浏览器垃圾回收机制:“内存释放机制”
@1 堆内存的释放机制
  • 如果当前堆内存的16进制地址,被其它事物所引用,则堆内存不能释放掉「强引用」
  • 如果没有东西占用这个堆内存,浏览器在空闲时候,会把这些未被引用的堆内存“回收/释放”掉
/* let obj = {
    name: 'zhufeng'
};
obj.obj = obj;
obj = null; //让obj不指向对象的堆内存,这样上述对象就可以被释放掉了「手动释放堆内存的方法:赋值为null」 */
@2 栈内存(执行上下文)的释放机制
  • 全局上下文是加载页面的时候产生的,也只有关闭页面的时候才会释放
  • 私有上下文(不论是函数还是块),一般情况,执行完都会出栈释放掉,以此来优化栈内存;但是有特殊情况,如果当前上下文中创建的某个东西(一般指一个对象{堆内存}),被上下文以外的其它事物占用了,那么不仅创建的这个东西不能被释放,和其有关联的这个私有上下文也不能释放!!
  • 消耗内存「慎用」
  • 因为不被释放,所以这个私有上下文中的东西都被保留下来的,以后可以拿来用
let a = 0,
   b = 0;
function A(a) {
   // 函数重构:第一次执行A函数,内部把A改为里面的小函数;所以以后再执行A,
   执行的都是里面的小函数;
   A = function (b) {
       alert(a + b++);
   };
   alert(a++);
};
A(1);
A(2); 

重复声明问题

var/function语法上允许相同上下文中“重复去声明一个变量”,只不过浏览器渲染的时候,不会去重复声明;但是let/const/class,从语法上就不支持重复声明「报SyntaxError」,而且所谓的不允许重复声明,是不论当前上下文中,我们基于何种方式,是要声明过这个变量,那么绝对不允许再拿let/const/class声明了;

  • 检测是否重复声明的事情,不是发生在代码执行阶段,而是在“词法分析阶段”,如果有重复声明的语法错误,则AST都不会生成{词法解析不通过},JS中所有代码也都不会在执行了!!
  • 词法分析:
    @1 我们从服务器端获取的到JS代码,本质是一堆字符串,而浏览器会把这堆字符串,按照ECMA262规范,解析为自己可以识别的JS代码…我们把这个过程,称之为“词法分析/解析”
    @2 词法分析阶段,会把这堆代码变为浏览器可以识别的“树形结构 -> AST语法树”

    THIS问题

    THIS的几种基本情况
  • 事件绑定
  • 函数执行
  • 匿名函数
  • 成员访问
  • 普通函数
  • 回调函数…

全局的THIS是window对象{GO};块级私有上下文中没有自己的THIS,遇到的THIS是“宿主环境”中的;所以我们研究的THIS都是指:函数执行,产生的私有上下文中的THIS;
THIS:函数的执行主体“谁把它执行的”,和函数在哪创建以及在哪执行都没啥关系!!以后遇到this,一句话“你以为你以为的就是你以为的”,冷静、冷静、冷静…按照总结的规律去套即可!!
@1 给当前元素的某一个事件行为绑定方法,当事件行为触发,浏览器会帮我们把绑定的方法执行,此时方法中的this是当前操作的元素本身
@2 函数执行,看函数前面是否有“点”

  • 没有:非严格模式下this->window 严格模式下this->undefined
  • 有:“点”前面是谁this就是谁
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南笙前端工程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值