1. JS编译解析的流程

1.1 JS运行分三步

语法分析(通篇扫描是否有语法错误),预编译(发生在函数执行的前一刻),解释执行(一行行执行)。

1.2 预编译执行分五步

  1. 创建AO对象(Activation Object  执行期上下文)

  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined. 变量声明提升(变量放到后面也不会报错,只是未定义类型)如:console.log(a);var a=10;结果undenfined;

  3. 将实参值和形参统一(传参)

  4. 在函数体里面找到函数声明{函数声明整体提升(相当于放到程序最前面)}

  5. 值赋予函数体,执行(声明函数和变量的部分直接不看了)

2. 函数作用域和作用域链

2.1 函数作用域

每个javascript函数都是一个对象,对象中有的属性可以访问,有的不能,这些属性仅供javascript引擎存取,如[[scope]]。

[[scope]]就是函数的作用域,其中存储了执行期上下文的集合。

执行期上下文: 当函数执行时,会创建一个称为执行期上下文的内部对象(AO)。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行期上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行期上下文,当函数执行完毕,它所产生的执行上下文被销毁。

2.2 作用域链

[[scope]]中所存储的执行期上下文对象的集合,这个集合呈链式链接,我们称这种链式链接为作用域链。查找变量时,要从作用域链的顶部开始查找。Activation Object(AO)到Global Object(GO)。

2.3 闭包

[!NOTE]

当内部函数被保存到外部时,将会生成闭包。生成闭包后,内部函数依旧可以访问其所在的外部函数的变量。

闭包问题的解决方法:立即执行函数、let

2.3.1 详细解释

  1. 当函数执行时,会创建一个称为执行期上下文的内部对象(AO),执行期上下文定义了一个函数执行时的环境。

  2. 函数还会获得它所在作用域的作用域链,是存储函数能够访问的所有执行期上下文对象的集合,即这个函数中能够访问到的东西都是沿着作用域链向上查找直到全局作用域。

  3. 函数每次执行时对应的执行期上下文都是独一无二的,当函数执行完毕,函数都会失去对这个作用域链的引用,JS的垃圾回收机制是采用引用计数策略,如果一块内存不再被引用了那么这块内存就会被释放。

  4. 但是,当闭包存在时,即内部函数保留了对外部变量的引用时,这个作用域链就不会被销毁,此时内部函数依旧可以访问其所在的外部函数的变量,这就是闭包。

2.3.2 闭包的应用

先看两个例子,两个例子都打印5个5

for (var i = 0; i < 5; i++) {
setTimeout(function timer() {
console.log(i)
}, i * 100)
}
function test() {
var a = [];
for (var i = 0; i < 5; i++) {
a[i] = function () {
console.log(i);
}
}
return a;
} var myArr = test();
for(var j=0;j<5;j++)
{
myArr[j]();
}

解决方法: 使用立即执行函数

for (var i = 0; i < 5; i++) {
;(function(i) {
setTimeout(function timer() {
console.log(i)
}, i * 100)
})(i)
}
function test(){
var arr=[];
for(i=0;i<10;i++)
{
(function(j){
arr[j]=function(){
console.log(j);
}
})(i)
}
return arr;
} var myArr=test();
for(j=0;j<10;j++)
{
myArr[j]();
}

2.3.3 闭包-封装私有变量

function Counter() {
let count = 0;
this.plus = function () {
return ++count;
}
this.minus = function () {
return --count;
}
this.getCount = function () {
return count;
}
} const counter = new Counter();
counter.puls();
counter.puls();
console.log(counter.getCount())

3. 作用域与变量声明提升?

  1. 在 JavaScript 中,函数声明与变量声明会被 JavaScript 引擎隐式地提升到当前作用域的顶部
  2. 声明语句中的赋值部分并不会被提升,只有名称被提升
  3. 函数声明的优先级高于变量,如果变量名跟函数名相同且未赋值,则函数声明会覆盖变量声明
  4. 如果函数有多个同名参数,那么最后一个参数(即使没有定义)会覆盖前面的同名参数

4. 构造函数,new时发生了什么?

   var obj  = {};
obj.__proto__ = Base.prototype;
Base.call(obj);
  1. 创建一个新的对象 obj;
  2. 将这个空对象的__proto__成员指向了Base函数对象prototype成员对象
  3. Base函数对象的this指针替换成obj, 相当于执行了Base.call(obj);
  4. 如果构造函数显示的返回一个对象,那么则这个实例为这个返回的对象。 否则返回这个新创建的对象

5. 函数参数是对象会发生什么问题?

function test(person) {
person.age = 26
person = {
name: 'yyy',
age: 30
} return person
}
const p1 = {
name: 'hy',
age: 25
}
const p2 = test(p1)
console.log(p1) // -> {name: "hy", age: 20}
console.log(p2) // -> {name: "yyy", age: 30}

person = {} 这一步操作就将应用与原来的分离了

6. JavaScript 中,调用函数有哪几种方式?

  1. 方法调用模式 Foo.foo(arg1, arg2);
  2. 函数调用模式 foo(arg1, arg2);
  3. 构造器调用模式 (new Foo())(arg1, arg2);
  4. call/applay 调用模式 Foo.foo.call(that, arg1, arg2);
  5. bind 调用模式 Foo.foo.bind(that)(arg1, arg2)();

【前端知识体系-JS相关】你真的了解JavaScript编译解析的流程吗?的更多相关文章

  1. 【前端知识体系-JS相关】深入理解JavaScript异步和单线程

    1. 为什么JavaScript是单线程? JavaScript语言的一大特点就是单线程,也就是说,同一个时间只能做一件事.那么,为什么JavaScript不能有多个线程呢?这样能提高效率啊. Jav ...

  2. 【前端知识体系-JS相关】深入理解JavaScript原型(继承)和原型链

    1. Javascript继承 1.1 原型链继承 function Parent() { this.name = 'zhangsan'; this.children = ['A', 'B', 'C' ...

  3. 【前端知识体系-JS相关】对移动端和Hybrid开发的理解?

    1.hybrid是什么,为何使用hybrid呢? 概念: hybrid就是前端和客户端的混合开发 需要前端开发人员和客户端开发人员配合完成 某些环节也可能会涉及到server端 大前端:网页.APP. ...

  4. 【前端知识体系-JS相关】JS基础知识总结

    1 变量类型和计算 1.1 值类型和引用类型的区别? 值类型:每个变量都会存储各自的值.不会相互影响 引用类型:不同变量的指针执行了同一个对象(数组,对象,函数) 1.2 typeof可以及检测的数据 ...

  5. 【前端知识体系-JS相关】深入理解MVVM和VUE

    1. v-bind和v-model的区别? v-bind用来绑定数据和属性以及表达式,缩写为':' v-model使用在表单中,实现双向数据绑定的,在表单元素外使用不起作用 2. Vue 中三要素的是 ...

  6. 【前端知识体系-JS相关】组件化和React

    1. 说一下使用jQuery和使用框架的区别? 数据和视图的分离,(jQuery数据和视图混在一起,代码耦合)-------开放封闭原则 以数据驱动视图(只关注数据变化,DOM操作被封装) 2.说一下 ...

  7. 【前端知识体系-JS相关】ES6专题系列总结

    1.如何搭建ES6的webpack开发环境? 安装Node环境 node -v // 10.14.1 安装NPM环境 npm -v // 6.4.1 安装babel npm install @babe ...

  8. 【前端知识体系-JS相关】JS-Web-API总结

    2.1 DOM操作 2.1.1 DOM的本质是什么? <!-- DOM树:二叉树 --> /* <?xml version="1.0" encoding=&quo ...

  9. 【前端知识体系-JS相关】10分钟搞定JavaScript正则表达式高频考点

    1.正则表达式基础 1.1 创建正则表达式 1.1.1 使用一个正则表达式字面量 const regex = /^[a-zA-Z]+[0-9]*\W?_$/gi; 1.1.2 调用RegExp对象的构 ...

随机推荐

  1. maven 上传jar包到私服仓库

    按一下形式上传jiar包 # mvn deploy:deploy-file -DgroupId=com.itextpdf -DartifactId=itextpdf -Dversion=5.5.13 ...

  2. java程序猿工具

    1.做为一个程序员打字最重要    指法打字练习软件:http://home.bdqn.cn/thread-11142-1-1.html 2.JDK必不可少    JDK6.X下载       JDK ...

  3. csp2019后的感慨

    你还记得曾经加入oi的初衷吗? ... 我们都不想输,可谁都没有赢... --前言 没有太大的感想,也不配去写感想...就记录一下初学者失败的原因吧.希望看过的人能引以为戒. 做题的时候,不到万不得已 ...

  4. IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 HTML基础标签

    指引 网页中的信息主要是以文本为主的,可以通过字体.大小.颜色.底纹.边框等来设置文本的属性.文字版面的编辑包括文本标签和格式标签两种,在浏览器中显示的文字内容和格式都要在<body>标记 ...

  5. IT兄弟连 HTML5教程 HTML5做到了与之前版本的兼容

    为了保证HTML5能与之前的HTML版本达到最大的兼容,HTML5对一些元素标记的省略.boolean值的属性,以及引号的省略这几方面进行了兼顾,确保与之前版本的HTML达到兼容.在下面示例中,将本节 ...

  6. C# winfrom调用摄像头扫描二维码(完整版)

    前段时间看到一篇博客,是这个功能的,参考了那篇博客写了这个功能玩一玩,没有做商业用途.发现他的代码给的有些描述不清晰的,我就自己整理一下发出来记录一下. 参考博客链接:https://www.cnbl ...

  7. OpenCV:图像的开运算与闭运算

    导包: import numpy as np import cv2 import matplotlib.pyplot as plt def show(image): plt.imshow(image) ...

  8. CSAPP 2-1 - 信息的存储

    目录 0 基础概念及摘要 1 信息存储 1.1 十六进制表示法 1.2 字数据大小 1.3 寻址和字节顺序 0 基础概念及摘要 (1) 基础概念: 现代计算机存储和处理的信息以二进制信号表示 -- 0 ...

  9. 26-限制容器对CPU的使用

    默认设置下,所有容器可以平等地使用 host CPU 资源并且没有限制. Docker 可以通过 -c 或 --cpu-shares 设置容器使用 CPU 的权重.如果不指定,默认值为 1024. 与 ...

  10. easyui textbox setValue以及setText的使用技巧

    1.先赋值Value,后赋值Text $('#Name').textbox('setValue', "11");$('#Name').textbox('setText', &quo ...