这是我参与「第四届青训营 」笔记创作活动的第5天
js特点:
- 垃圾收集机制
- 解释性语言
- 多范式语言:程序化,面向对象,函数式编程
- 基于对象的原始类型、原型链
- 函数一流
- 动态语言
- 单线程
- 非阻塞事件循环并发模型
引擎(发动机):谷歌-----v8,nodejs
执行上下文包含:变量环境、作用域链、this关键字
执行:调用栈+堆、前者是代码执行的地方,即执行上下文的内容,保证了执行顺序永远不会丢失;后者放对象,即时编译功能,编译+解释同时进行(不是纯解释性语言)
过程:解析代码->变成抽象语法树/AST(代码片段)-> 编译成机器码 -> 执行 (后台进行代码优化继续编译 为了提高速度) web API:DOM 定时器 访问API,运行时的一部分
回调队列:单击,事件循环放入堆栈循环执行(非阻塞特点)
nodejs执行时无 webAPI部分,因为其是浏览器提供的
范围与范围链:定义变量哪里可以被执行
工作方式:先查找本作用域的变量,若查找不到,向上寻找父作用域的变量使用,可以访问父范围但不能访问子范围,适用于let、const定义的变量因为它们均为块作用域,var是函数作用域,可以在函数中使用
可迭代对象:除了对象数据类型都可以
数组解构的元素名任意,但次序必须对应
对象解构次序无所谓,元素名必须和已定义对象相同
作用域小结:
作用域分类
定义:在js中,作用域是变量,对象,函数可访问的一个范围。
分类:全局作用域,局部作用域,块级作用域
全局作用域:全局代表了整个文档document,变量或者函数在函数外面声明,那它的就是全局变量和全局函数。之所以全局变量在这个文档的任何位置都可以访问是因为它是window下的属性,window是一个全局对象,它本身在页面中任何位置可以用,同样它身上的属性在页面的任何位置也是可以用的。
声明全局作用域的方法:把变量或者是函数放在函数外声明或者变量不用var声明直接赋值(不管是在函数内还是函数外它都是一个全局变量).要避免使用全局变量,声明变量的时候一定要加上var.
局部作用域:变量在函数内声明,变量为局部作用域。只能在函数内部访问。所以不同函数可以使用相同名称的变量。函数执行完后局部变量会自动销毁。函数可以嵌套,嵌套的函数可以访问父函数里的内容。
声明局部作用域的方法:var 变量,function 函数名(){}.
什么是作用域链,可以简单的将作用域链理解为变量与函数的查找规则。
查找规则:如是一个函数需要用到一个变量,那它会先在自己的作用域里去找这个变量,如果自己有那它就直接用自己的,如果自己没有,那它就会一层层向外面找,直到找到外层的变量,找到后就用外层的变量(只会向外,不会向内找)。
变量提升:
通过前面的知识我们得知,在当前上下文中,js代码自上而下执行之前,浏览器首先会把当前上下文中所有带“var / function”关键字进行提前的声明和定义,解析到它们对应作用域开始的位置(也可以理解为这是词法解析的一个环节,语法解析发生在代码执行前)这种预先处理的机制叫做变量提升,变量提升的意义在于创建变量前使用这个变量不报错。变量提升也可以称之为预解析。
声明(declare): var a / function sum(默认值为undefined)
定义(defined): a = 12(定义其实就是赋值操作)
在变量提升阶段,带var的只声明未定义,而带function声明和定义都完成了。
变量提升只发生在当前作用域(如:开始加载页面的时候只对全局作用域下的进行提升,因为此时函数中存储的都是字符串而已);浏览器很懒,做过的事情不会重复的执行,也就是当代码执行遇到创建函数这部分代码后,直接跳过(在提升阶段已经完成了函数的赋值操作)。
私有作用域中,带var的在变量提升阶段,声明为私有变量,与外界无关。不带var不是私有变量,会向上级作用域查找,看是否为上级的变量,不是,继续向上查找,它的上级作用域是谁和它在哪里执行无关,和它在哪里创建有关,在哪里创建,它的上级作用域就是谁。