关于前端:浏览器网页浏览器

30次阅读

共计 2856 个字符,预计需要花费 8 分钟才能阅读完成。

浏览器(网页浏览器)

参考:百科:浏览器

词条:浏览器、内核、浏览器内核、javascript 引擎

1. 浏览器的组成

​ 浏览器大抵由 shell内核 组成

​ shell 包含外壳,菜单,用户操作界面 等等

​ 内核个别分为 渲染引擎 (排版渲染引擎、图形引擎) 和 javascript 引擎 (JS 解释器)

​ shell(计算机壳层):是指“为使用者提供操作界面”的软件(command interpreter,命令解析器)

​ shell 相似于 DOS 下的 COMMAND.COM 和起初的 cmd.exe。它接管用户命令,而后调用相应的应用程序。

2. 主流程 The main flow

​ 渲染引擎在获得内容之后的根本流程:

​ 解析 html 以 构建 dom 树 -> 构建 render 树 -> 布局 render 树 -> 绘制 render 树

​ 参考:https://blog.csdn.net/liyong1…

3. 浏览器内核技术

​ 浏览器内核次要包含以下三个技术分支:排版渲染引擎、JavaScript 引擎,以及其余

4. 浏览器的内核(渲染引擎、浏览器引擎、Rendering Engine)

浏览器引擎(内核,渲染引擎)-用来查问及操作渲染引擎的接口

​ 例如:webkit【WebKit 所蕴含的 WebCore 排版引擎JavaScriptCore 解析引擎】、

​ Trident、Gecko、Presto

排版渲染引擎-用来显示申请的内容

​ 例如:WebCore

JavaScript 引擎-用来“读懂”JavaScript 代码 并 解释执行 JS 代码

​ 例如:V8

5.JavaScript 引擎

JavaScript 引擎 是一个专门解决 JavaScript 脚本的虚拟机,个别会附带在网页浏览器之中。

​ 例如:V8,由 Google 丹麦开发,是 Chrome 浏览器的一部分。

6.JavaScript 引擎工作原理

​ 参考:https://blog.csdn.net/a419419…

6.1 第一阶段:语法查看
6.1.1 词法剖析

​ JavaScript 解释器先把 JavaScript 代码(字符串)的字符流依照 ECMAScript 规范转换为记号流

6.1.2 语法分析

​ JavaScript 语法分析器在通过词法剖析后,将记号流依照 ECMAScript 规范把词法剖析所产生的记号生成语法树。艰深地说就是把从 程序中收集的信息存储到数据结构中,每取一个词法记号,就送入语法分析器进行剖析。

6.2 第一阶段:运行阶段
6.2.1 预解析

​ 第一步:创立执行上下文。解析器将语法查看正确后生成的语法树复制到以后执行上下文中。

​ 第二步:属性填充。解析器会对语法树当中的变量申明、函数申明以及函数的形参进行属性填充。

​ 预解析阶段创立的执行上下文包含:变量对象、作用域链、this

​ 变量对象(Variable Object):由 vardeclaration、function declaration(变量申明、函数申明)、arguments(参数)形成。变量对象是以单例模式存在。

​ 作用域链(Scope Chain):variableobject + all parent scopes(变量对象以及所有父级作用域)形成。

​ this 值:(thisValue):contentobject。this 值在进入上下文阶段就确定了。一旦进入执行代码阶段,this 值就不会变了。

6.2.2 执行

​ 注:圆括号 () 是一种运算符,跟在函数名之后,示意调用该函数。

​ 函数名称() 或者 参数名称.call()

js 运行三部曲
1、语法分析
2、预编译
3、解释执行
预编译
1、创立 AO 对象(执行器上下文、执行环境)2、找形参和变量申明、将变量和形参作为 AO 的属性名. 值为 undefined
3、将实参值和形参值对立
4、在函数体内找到函数申明,值赋予函数体
注:变量对象初始化程序:函数形参 --> 函数申明 --> 变量申明;(也是晋升程序)[[Scope]]仅供 js 引擎操作
作用域 \ 作用域链
function fn() {// 创立 Ao 对象(Activation Object) 执行器上下文
    // 伪代码
    var AO = {
        this: window,        // 构造函数相干
        '[[Scope]]': 'GO',     // 所在环节的作用域 */
        num: undefined,    
    };
    var num = 123;
}
fn();

// 全局作用域
var GO = {
    this: window,
    window: (Object),
    document: (Object),
    fn: undefined
}
【对象】字面量(构造函数(一般函数(预编译)))和间接量
构造函数外部原理【实例、构造函数、对象】

原型链的连接点:__proto__

call/apply:扭转 this 指向

call/apply 区别:传参列表不同

// 模仿构造函数(构造函数原理)
function Object() {// 1、在函数体最背后隐士的加上 this = {}
    // 2、执行 this.xxx = xxx;
    // 3、隐式地返回 this(援用类型)var this = {
        __proto__: Object.prototype,    // 能够被批改
        contructor: Object,                // 构造函数
        arguments: null                    // 形参    https://zhuanlan.zhihu.com/p/72469390
    };
    this.name = 'zhangcs';
    return this;                
}

// 原型
Object.prototype = {name: '原型'}

// 实例
new Object().name;             // 指向属性 'zhangcs'
new Object().contructor;    // 指向构造函数
new Object().__proto__;        // 指向原型

// 扭转 this 指向
var obj = {}
Object.call(obj, '参数');            // this = obj
Object.apply(obj, ['参数']);        // 参数必须是数组     

function Model(width) {this.width = width;}
function Style(color) {this.color = color;}
function Car(color, width) {Model.call(this, width);
    Style.apply(this, [color]);
};
var car = new Car('red', '200')

7. 工作队列

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

​ JavaScript 的单线程,与它的用处无关。作为浏览器脚本语言,JavaScript 的主要用途是与用户互动,以及操作 DOM。这决定了它只能是单线程,否则会带来很简单的同步问题。比方,假设 JavaScript 同时有两个线程,一个线程在某个 DOM 节点上增加内容,另一个线程删除了这个节点,这时浏览器应该以哪个线程为准?

​ 单线程就意味着,所有工作须要排队,前一个工作完结,才会执行后一个工作。如果前一个工作耗时很长,后一个工作就不得不始终等着。

正文完
 0