- Published on
javascript核心概念
- Authors
- Name
- Reeswell
javascript核心概念
this 绑定规则
- 默认绑定:在非严格模式下,
this
指向全局对象(浏览器中是window
) - 隐式绑定:当函数引用有上下文对象时,
this
绑定到这个上下文对象 - 显式绑定:使用
apply
、call
、bind
时,this
被绑定到指定的对象 - new 绑定:在构造函数中,
this
指向new
出来的那个对象
闭包
定义:闭包通常是一个函数内部定义的函数。内部函数可以访问外部函数的作用域。当内部函数作为外部函数的返回值返回时,即使外部函数执行完毕,内部函数依然能访问外部函数的变量。
应用场景:
- 封装私有变量
- 实现模块化
- 防抖节流函数
缺点:处理不当容易导致内存泄漏
作用域
定义:作用域是指当前上下文中,变量和函数的可访问范围。不在可访问范围内的变量则不可用。作用域可以是嵌套结构,子作用域可以访问父作用域,反过来则不行。
常见的作用域类型:
- 全局作用域:脚本模式下运行所有代码的作用域
- 函数作用域:函数内部的作用域
- 块级作用域:
let
、const
声明的变量具有块级作用域
作用域链
当在 JavaScript 中使用一个变量的时候,首先 JavaScript 引擎会尝试在当前作用域下去寻找该变量,如果没找到,再到它的上层作用域寻找,以此类推直到找到该变量或是已经到了全局作用域。
如果在全局作用域里仍然找不到该变量,它就会在全局范围内隐式声明该变量(非严格模式下)或是直接报错。
原型
JavaScript 常被描述为一种基于原型的语言——每个对象拥有一个原型对象。
当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。
准确地说,这些属性和方法定义在 Object
的构造器函数(constructor functions)之上的 prototype
属性上,而非实例对象本身。
原型链
原型对象也可能拥有原型,并从中继承方法和属性,一层一层、以此类推。这种关系常被称为原型链(prototype chain),它解释了为何一个对象会拥有定义在其他对象中的属性和方法。
在对象实例和它的构造器之间建立一个链接(它是 __proto__
属性,是从构造函数的 prototype
属性派生的),之后通过上溯原型链,在构造器中找到这些属性和方法。
异步编程
任务队列、宏任务、微任务
底层机制
JavaScript 引擎(如 V8)与宿主环境(如浏览器或 Node.js)共同维护事件循环。宿主环境负责将异步任务根据类型放入对应的队列。
异步任务可以分为宏任务、微任务。
宏任务队列(Macro Task Queue)
每个宏任务是一个独立的执行单元。 常见的宏任务有:
script
(整体代码)setTimeout
setInterval
- I/O 操作(如文件读写、网络请求完成)
- UI 渲染(浏览器中)
MessageChannel
postMessage
setImmediate
requestAnimationFrame
requestIdleCallback
宏任务被放入宏任务队列,事件循环每次从队列头部取出一个执行。
微任务队列(Micro Task Queue)
微任务在当前宏任务执行结束后立即执行,且必须全部执行完。 常见的微任务有:
Promise.then
/catch
/finally
MutationObserver
queueMicrotask
process.nextTick
(Node.js 特有) 微任务队列在每次宏任务结束后被“清空”——即所有微任务按入队顺序依次执行,中途新加入的微任务也会被执行。
执行顺序规则
- 执行一个宏任务(如
script
主代码块)。 - 执行过程中产生的所有微任务会被加入微任务队列。
- 当前宏任务执行完毕后,立即清空微任务队列(按入队顺序依次执行所有微任务)。
- 然后从宏任务队列中取出下一个宏任务,重复上述过程。