深入理解JS

226 阅读4分钟

JS基本概念

image.png

数据类型

  • 复杂数据类型
  1. 对象
  2. 数组
  3. 函数
  4. ......
  • 基本数据类型
  1. 字符串
  2. undefined
  3. null
  4. 数字
  5. symbol
  6. bigint
  7. 布尔值

作用域

变量的可访问性和可见性
静态作用域,通过它就能够预测代码在执行过程中如何查找标识符

  • 全局作用域
var  company = "Bytedance"
function showCompany() {
console.log(company)
}
showCompany( )
  • 函数作用域
var  company ='Bytedance'
function showCompany() {
    company ="douyin"
    console.log(company)
}
showCompany()
  • 块级作用域
{
    const  company ="Bytedance";
    console.log(1,company);
}

console.log(2,company);

变量提升

console.log('company',company);
console.log( 'dep',  dep);
console.log('myname' , myname );
showInfo()
show()
const  company ="Bytedance"
let dep='边缘云'
var  myname = "zhangqi"

function showInfo(){
    console.log(company,dep, myname)
    console.log(myname)
}
var show= function (){
console.log(myname)
}
  • var有变量提升
  • let、 const没有变量提升,提前访问会报错
  • function函数可以先调用再定义
  • 赋值给变量的函数无法提前调用

JS 如何执行

image.png

image.png

image.png

  • 全局执行上下文: 代码开始执行时就会创建,将他压执行栈的栈底,每个生命周期内只有一份
  • 函数执行上下文: 当执行一个函数时,这个函数内的代码会被编译,生成变量环境、词法环境等,当函数执行结束的时候该执行环境从栈顶弹出
var scop = 'global';
func();
console.log(company);
function func(){
    var funcVar = 'func';
    console.log('这是个函数',funcVar);
}
var company = '字节跳动';

image.png

  • 词法环境: 基于 ECMAScript 代码的词法嵌套结构来定义标识符和具体变量和函数的关联。一人词法环境由环境记录器和一个可能的引用外部词法环境的空值组成

  • 变量环境: 变量环境和词法环境的一个不同就是前者被用来存储函数声明和变量 (let 和 const)绑定,而后者只用来存储 var 变量绑定

  • Outer: 指向外部变量环境的一个指针

image.png

JS进阶知识点

闭包

function showName(){
    const company="Bytedance"
    const dep="边缘云"
    const name = "zhangqi";
    console.log( 'company ',  company);
    return function (){
        console.log(dep);
        return name
    }
}
const getName = showName( )
console.log(getName( ));

image.png

这里我想到之前看过的一个闭包,这里分享给大家

var a = '123'
function fo1(){
    var a = 'foo'
    function fo(){
        console.log(a)
    }
    return fo
}

function f(p){
    var a = 'f'
    p()
}
f(fo1())
/* 输出
*   foo
/ 
//使用 return fo 返回回来,fo() 就是闭包,f(foo()) 执行的参数就是函数 fo,因为 fo() 中的 a 的上级作用域就是函数foo(),所以输出就是foo*/
---------------------------------------------------------------
/*以下是变量提升例子*/
var a;var b;
console.log(a, b)
var a =12, b ='陈'
function foo(){
    var a;
    console.log(a, b)
    var a = b =13
    console.log(a, b)
}
foo()
console.log(a, b)
// u  u
// u  陈
// 13 13
//12  13

闭包找到的是同一地址中父级函数中对应变量最终的值

闭包作用及坏处

  1. 好处
  • 保护函数的私有变量不受外部的干扰。形成不销毁的栈内存。
  • 把一些函数内的值保存下来。闭包可以实现方法和属性的私有化
  1. 坏处
  • 容易导致内存泄漏。闭包会携带包含其它的函数作用域,因此会比其他函数占用更多的内存。过度使用闭包会导致内存占用过多,所以要谨慎使用闭包

this

function showName(){
console.log(this)
}

image.png

const  personObj={
    name:'zhangqi"
    dep:"边缘云'
    showName(){
        console.log(this.name)
    }
}
personObj.showName( )
const getName =personObj.showName
getName()

image.png

function ShowName(){
    this.name ="zhangqi";
}
const  getName =new ShowName()

image.png

垃圾回收

image.png

总结

  1. JS是单线程的,但是Render进程里面有多个线程
  2. JS线程和GUI线程互斥,执行大的计算任务会导致页面卡顿
  3. 基础数据类型存在栈上,复杂数据类型存在堆上
  4. const、let没有变量提升,提前使用会报错
  5. JS也有编译的过程,执行之前会生成执行上下文
  6. 一个执行上下文包括变量环境、词法环境、this
  7. 变量环境里面有一个指向外部函数执行上下文的指针,形成了作用域链
  8. 全局执行上下文只有一份
  9. this 和执行上下文绑定

通过这一节课的介绍,包括我自己在内也学到了许多,虽然是个大概,但却对JS有了个全面的了解,我自己也去掘金网站上搜索了关于JS执行流程的介绍,发现有了更加全面的介绍,这里我也给大家推荐几篇好文

JS 闭包经典使用场景和含闭包必刷题 - 掘金 (juejin.cn)

闭包例子大全

深入理解JS执行流程 - 掘金 (juejin.cn)