JavaScript
执行上下文
执行上下文(Execution Context
)是 JavaScript
引擎在执行代码时所创建的一个抽象概念,用于跟踪代码的执行状态和变量的生命周期。每当 JavaScript
代码开始执行,就会创建一个全局执行上下文,并且在函数调用时会创建对应的函数执行上下文。
执行上下文由三个主要组成部分构成:
变量环境(
Variable Environment
):变量环境存储了当前执行上下文中声明的变量和函数的引用。它是一个词法环境的实例,可以通过此环境访问和解析标识符。变量环境在创建执行上下文时进行初始化,在执行过程中可以修改和更新其中的变量和函数。词法环境(
Lexical Environment
):词法环境是执行上下文的另一个重要组成部分,它与变量环境非常相似,也是一个存储变量和函数标识符与它们对应值之间关联的数据结构。词法环境负责存储并解析标识符,在执行过程中根据作用域链来查找变量和函数。this 值(
This Binding
):this
值指向当前执行上下文中正在执行的函数的上下文对象。它在函数调用时动态确定,取决于函数的调用方式。this
值在执行上下文创建时被绑定,并在整个执行过程中保持不变。
除了这三个主要组成部分外,执行上下文还包含其他属性和信息,如函数参数、闭包引用等。
在 JavaScript
中,执行上下文形成一个栈结构,称为执行上下文栈(Execution Context Stack
)或调用栈(Call Stack
)。每当函数被调用时,就会创建一个新的函数执行上下文,并被推入执行上下文栈的顶部。当函数执行完毕后,对应的执行上下文会从栈顶弹出。通过执行上下文栈,JavaScript
引擎能够跟踪代码的执行过程,并在需要时访问和管理执行上下文中的变量和函数。
TIP
总结起来,执行上下文是 JavaScript
引擎在执行代码时所创建的一个抽象层面的概念,它包含了变量环境、词法环境和 this
值等信息,用于跟踪代码的执行状态和变量的生命周期。执行上下文栈则用于存储和管理多个执行上下文,实现函数调用的嵌套和控制流的管理。
数据类型检测
typeof
typeof null => "object"
typeof 不能细分对象类型的值, 返回结果都是"object" [检测函数返回"function"]
typeof 10 => "number"
typeof new Number(10) => "object"
底层原理: typeof是按照"值"在计算机中存储的"二进制"值来检测的, 凡是以000开始的都认为是对象, null => 000000
优势: 使用方便, 检测原始值类型和函数类型很方便
instanceof
检测某个实例是否隶属于某个类 [临时拉来做数据类型检测]
不能检测原始值类型
原型链可以被肆意重构, 导致结果不准确
底层原理 (例: xxx instanceof Ctor)
首先调用Symbol.hasInstance, 存在就基于这个检测
jsCtor[Symbol.hasInstance](xxx)
如果没有, 就基于原型链proto查找: 只要Ctor.prototype出现在xxx的原型链上, 结果就是true
Object.prototype.toString.call(val)
除了null/undefined, 大部分数据类型所属类的原型上, 都有toSting方法; 但是除了Object.prototype.toString用来检测数据类型, 其余的都是转换为字符串的
返回值: "[object ?]"
- 先查找[val]上的Symbol.toStringTag [先找私有的, 私有没有则向所属类原型上找], 属性值就是"?"的值
- 没有则内部是返回当前实例所属构造函数的名字
路由模式
前端路由模式是一种在前端应用中管理页面导航和路由的方式。它允许在单页应用(Single-Page Application
,SPA
)中实现多个虚拟页面的效果,而无需每次导航都向服务器发送请求。
以下是几种常见的前端路由模式:
Hash 模式:在
URL
中使用哈希(#
)来表示路由路径。当URL
中的哈希值发生变化时,前端路由会根据哈希值的变化来切换页面内容。例如:http://example.com/#/home
。History 模式:使用
HTML5
的History API
来管理路由。通过修改浏览器的历史记录,可以实现无刷新页面的导航。URL
中不再需要哈希,而是直接使用真实的路径。例如:http://example.com/home
。Memory 模式:在内存中管理路由状态,而不改变浏览器的
URL
。这种模式通常用于一些特殊场景,例如在Electron
或React Native
等桌面或移动应用中。
INFO
不同的前端框架和库可能会提供不同的路由模式实现。例如,React Router
提供了 HashRouter
和 BrowserRouter
组件来支持 Hash
模式和 History
模式。
TIP
选择适合的前端路由模式取决于项目需求和开发团队的偏好。Hash
模式在兼容性方面更好,但 URL
中会有哈希值。History
模式更加直观和美观,但需要服务器配置支持。在选择路由模式时,还需要考虑到搜索引擎优化(SEO
)和用户体验等因素。
Hash 路由
Hash
路由是一种前端路由模式,它使用 URL
中的哈希(#
)来表示路由路径。在 Hash
路由模式下,当 URL
中的哈希值发生变化时,前端路由会根据哈希值的变化来切换页面内容,而无需向服务器发送请求。
以下是 Hash
路由的一些特点和用法:
URL 格式:在
Hash
路由中,URL
的格式通常是http://example.com/#/path
, 其中/path
表示路由路径。哈希符号(#
)后面的内容被称为哈希值,用于标识不同的路由。无刷新导航:当用户点击带有不同哈希值的链接时,浏览器不会向服务器发送请求,而是触发前端路由的变化事件。前端路由会根据哈希值的变化来切换页面内容,实现无刷新导航。
监听哈希变化:前端框架或库通常提供了监听哈希变化的方法,可以在哈希值发生变化时执行相应的操作。例如,可以监听
hashchange
事件或使用路由库提供的 API 来处理哈希变化。传递参数:
Hash
路由可以通过在哈希值中添加参数来传递数据。例如,http://example.com/#/user/123
表示访问用户 ID 为 123 的用户页面。兼容性:
Hash
路由在各种浏览器中都有良好的兼容性,包括旧版本的浏览器。这是因为哈希值的变化不会触发页面的刷新,而是由前端路由来处理。
TIP
尽管 Hash 路由在一些方面具有一些限制,例如 URL
中会有哈希值,但它仍然是一种简单且可靠的前端路由模式。它适用于大多数前端应用,并且易于实现和维护。然而,随着现代浏览器对 History API
的支持越来越好,许多开发者更倾向于使用 History
路由模式来获得更直观和美观的 URL。
History 路由
history
路由是一种在前端应用中管理页面导航和路由的方式,它使用浏览器的 History API
来实现无刷新页面的导航。
下面是 history
路由的一些特点:
无刷新导航:
history
路由通过修改浏览器的URL
和历史记录来实现页面的切换,而无需向服务器发送请求。这意味着页面之间的切换是无刷新的,用户可以享受到更快速和平滑的导航体验。真实的 URL:与传统的哈希(#)路由相比,
history
路由使用真实的路径来表示页面的URL
。这使得URL
更加直观和美观,更符合传统的网页导航习惯。支持前进和后退:由于
history
路由使用浏览器的历史记录来管理导航,因此它天然地支持前进和后退操作。用户可以通过浏览器的前进和后退按钮来导航到之前访问过的页面。服务器配置:使用
history
路由需要服务器的支持。因为在history
路由中,URL
的路径是真实的,所以服务器需要配置来确保在访问不同路径时返回正确的页面内容。这通常涉及到配置一个通配符路由,以便将所有请求都指向应用的入口点。搜索引擎优化(SEO):由于
history
路由是在客户端进行的,搜索引擎的爬虫可能无法正确地解析和索引页面内容。为了解决这个问题,通常需要在服务器端实现服务器端渲染(Server-Side Rendering
,SSR
)或使用预渲染技术来提供给搜索引擎可索引的页面内容。
TIP
总的来说,history
路由提供了一种无刷新页面导航的方式,使用真实的 URL
路径,支持前进和后退操作。但它需要服务器的配置支持,并且在搜索引擎优化方面需要额外的处理。选择使用 history
路由还是其他路由模式取决于项目需求和开发团队的偏好。
Memory 路由
Memory
路由是一种前端路由模式,它在内存中管理路由状态,而不改变浏览器的 URL
。这种模式通常用于一些特殊场景,例如在 Electron
或 React Native
等桌面或移动应用中。
以下是 Memory
路由的一些特点:
无浏览器历史记录:
Memory
路由不会修改浏览器的URL
或历史记录。因此,用户无法通过浏览器的前进和后退按钮来导航页面。无法直接分享链接:由于没有改变
URL
,Memory
路由无法直接分享特定页面的链接。其他用户无法通过链接直接访问到特定的页面。适用于桌面和移动应用:
Memory
路由通常用于桌面和移动应用,其中应用的导航和页面切换是通过内部的路由机制来管理的,而不需要依赖浏览器的URL
。更高的性能:由于不需要修改浏览器的
URL
和历史记录,Memory
路由可以提供更高的性能。页面切换是在内存中进行的,不需要向服务器发送请求或加载新的页面资源。更灵活的路由控制:
Memory
路由可以提供更灵活的路由控制,开发者可以自定义路由逻辑和页面切换方式,以适应特定的应用需求。
TIP
需要注意的是,Memory
路由适用于特定的场景,例如桌面和移动应用,而不适用于传统的 Web
应用程序。在选择路由模式时,需要根据项目需求和应用场景来决定是否使用 Memory
路由。